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, 2016 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",
914 mdb_ctf_sizeof_by_name(const char *type
)
919 if (mdb_ctf_lookup_by_name(type
, &id
) == -1) {
920 mdb_warn("couldn't find type %s", type
);
924 if ((size
= mdb_ctf_type_size(id
)) == -1) {
925 mdb_warn("couldn't determine type size of %s", type
);
934 num_members_cb(const char *name
, mdb_ctf_id_t id
, ulong_t off
, void *data
)
942 mdb_ctf_num_members(mdb_ctf_id_t id
)
946 if (mdb_ctf_member_iter(id
, num_members_cb
, &count
) != 0)
947 return (-1); /* errno is set for us */
952 typedef struct mbr_contains
{
956 mdb_ctf_id_t
*mbc_idp
;
961 offset_to_name_cb(const char *name
, mdb_ctf_id_t id
, ulong_t off
, void *data
)
963 mbr_contains_t
*mbc
= data
;
968 if (*mbc
->mbc_offp
< off
)
971 if (mdb_ctf_type_encoding(id
, &e
) == -1)
972 size
= mdb_ctf_type_size(id
) * NBBY
;
976 if (off
+ size
<= *mbc
->mbc_offp
)
979 n
= mdb_snprintf(*mbc
->mbc_bufp
, *mbc
->mbc_lenp
, "%s", name
);
981 if (n
> *mbc
->mbc_lenp
)
987 *mbc
->mbc_offp
-= off
;
994 mdb_ctf_offset_to_name(mdb_ctf_id_t id
, ulong_t off
, char *buf
, size_t len
,
995 int dot
, mdb_ctf_id_t
*midp
, ulong_t
*moffp
)
1001 if (!mdb_ctf_type_valid(id
))
1002 return (set_errno(EINVAL
));
1005 * Quick sanity check to make sure the given offset is within
1006 * this scope of this type.
1008 if (mdb_ctf_type_size(id
) * NBBY
<= off
)
1009 return (set_errno(EINVAL
));
1011 mbc
.mbc_bufp
= &buf
;
1012 mbc
.mbc_lenp
= &len
;
1013 mbc
.mbc_offp
= &off
;
1021 * Check for an exact match.
1026 (void) mdb_ctf_type_resolve(id
, &id
);
1029 * Find the member that contains this offset.
1031 switch (mdb_ctf_type_kind(id
)) {
1033 mdb_ctf_arinfo_t ar
;
1036 (void) mdb_ctf_array_info(id
, &ar
);
1037 size
= mdb_ctf_type_size(ar
.mta_contents
) * NBBY
;
1040 id
= ar
.mta_contents
;
1043 n
= mdb_snprintf(buf
, len
, "[%u]", index
);
1053 case CTF_K_STRUCT
: {
1057 * Find the member that contains this offset
1070 ret
= mdb_ctf_member_iter(id
, offset_to_name_cb
, &mbc
);
1072 return (-1); /* errno is set for us */
1075 * If we did not find a member containing this offset
1076 * (due to holes in the structure), return EINVAL.
1079 return (set_errno(EINVAL
));
1086 * Treat unions like atomic entities since we can't
1087 * do more than guess which member of the union
1088 * might be the intended one.
1099 return (set_errno(EINVAL
));
1110 return (mbc
.mbc_total
);
1114 mdb_ctf_warn(uint_t flags
, const char *format
, ...)
1118 if (flags
& MDB_CTF_VREAD_QUIET
)
1121 va_start(alist
, format
);
1122 vwarn(format
, alist
);
1127 * Check if two types are structurally the same rather than logically
1128 * the same. That is to say that two types are equal if they have the
1129 * same logical structure rather than having the same ids in CTF-land.
1131 static int type_equals(mdb_ctf_id_t
, mdb_ctf_id_t
);
1134 type_equals_cb(const char *name
, mdb_ctf_id_t amem
, ulong_t aoff
, void *data
)
1136 mdb_ctf_id_t b
= *(mdb_ctf_id_t
*)data
;
1141 * Look up the corresponding member in the other composite type.
1143 if (mdb_ctf_member_info(b
, name
, &boff
, &bmem
) != 0)
1147 * We don't allow members to be shuffled around.
1152 return (type_equals(amem
, bmem
) ? 0 : 1);
1156 type_equals(mdb_ctf_id_t a
, mdb_ctf_id_t b
)
1160 mdb_ctf_arinfo_t aar
, bar
;
1163 * Resolve both types down to their fundamental types, and make
1164 * sure their sizes and kinds match.
1166 if (mdb_ctf_type_resolve(a
, &a
) != 0 ||
1167 mdb_ctf_type_resolve(b
, &b
) != 0 ||
1168 (asz
= mdb_ctf_type_size(a
)) == -1UL ||
1169 (bsz
= mdb_ctf_type_size(b
)) == -1UL ||
1170 (akind
= mdb_ctf_type_kind(a
)) == -1 ||
1171 (bkind
= mdb_ctf_type_kind(b
)) == -1 ||
1172 asz
!= bsz
|| akind
!= bkind
) {
1181 * For pointers we could be a little stricter and require
1182 * both pointers to reference types which look vaguely
1183 * similar (for example, we could insist that the two types
1184 * have the same name). However, all we really care about
1185 * here is that the structure of the two types are the same,
1186 * and, in that regard, one pointer is as good as another.
1193 * The test for the number of members is only strictly
1194 * necessary for unions since we'll find other problems with
1195 * structs. However, the extra check will do no harm.
1197 return (mdb_ctf_num_members(a
) == mdb_ctf_num_members(b
) &&
1198 mdb_ctf_member_iter(a
, type_equals_cb
, &b
) == 0);
1201 return (mdb_ctf_array_info(a
, &aar
) == 0 &&
1202 mdb_ctf_array_info(b
, &bar
) == 0 &&
1203 aar
.mta_nelems
== bar
.mta_nelems
&&
1204 type_equals(aar
.mta_index
, bar
.mta_index
) &&
1205 type_equals(aar
.mta_contents
, bar
.mta_contents
));
1212 typedef struct member
{
1215 const char *m_tgtname
;
1216 mdb_ctf_id_t m_tgtid
;
1220 static int vread_helper(mdb_ctf_id_t
, char *, mdb_ctf_id_t
, char *,
1221 const char *, uint_t
);
1224 member_cb(const char *name
, mdb_ctf_id_t modmid
, ulong_t modoff
, void *data
)
1226 member_t
*mp
= data
;
1227 char *modbuf
= mp
->m_modbuf
;
1228 mdb_ctf_id_t tgtmid
;
1229 char *tgtbuf
= mp
->m_tgtbuf
;
1233 (void) mdb_snprintf(tgtname
, sizeof (tgtname
),
1234 "member %s of type %s", name
, mp
->m_tgtname
);
1236 if (mdb_ctf_member_info(mp
->m_tgtid
, name
, &tgtoff
, &tgtmid
) != 0) {
1237 mdb_ctf_warn(mp
->m_flags
,
1238 "could not find %s\n", tgtname
);
1239 return (set_errno(EMDB_CTFNOMEMB
));
1242 return (vread_helper(modmid
, modbuf
+ modoff
/ NBBY
,
1243 tgtmid
, tgtbuf
+ tgtoff
/ NBBY
, tgtname
, mp
->m_flags
));
1246 typedef struct enum_value
{
1248 const char *ev_name
;
1252 enum_cb(const char *name
, int value
, void *data
)
1254 enum_value_t
*ev
= data
;
1256 if (strcmp(name
, ev
->ev_name
) == 0) {
1257 *ev
->ev_modbuf
= value
;
1264 vread_helper(mdb_ctf_id_t modid
, char *modbuf
,
1265 mdb_ctf_id_t tgtid
, char *tgtbuf
, const char *tgtname
, uint_t flags
)
1267 size_t modsz
, tgtsz
;
1268 int modkind
, tgtkind
, mod_members
;
1272 mdb_ctf_arinfo_t tar
, mar
;
1275 char mdbtypename
[128];
1276 ctf_encoding_t tgt_encoding
, mod_encoding
;
1277 boolean_t signed_int
= B_FALSE
;
1279 if (mdb_ctf_type_name(tgtid
, typename
, sizeof (typename
)) == NULL
) {
1280 (void) mdb_snprintf(typename
, sizeof (typename
),
1281 "#%ul", mdb_ctf_type_id(tgtid
));
1283 if (mdb_ctf_type_name(modid
,
1284 mdbtypename
, sizeof (mdbtypename
)) == NULL
) {
1285 (void) mdb_snprintf(mdbtypename
, sizeof (mdbtypename
),
1286 "#%ul", mdb_ctf_type_id(modid
));
1289 if (tgtname
== NULL
)
1293 * Resolve the types to their canonical form.
1295 (void) mdb_ctf_type_resolve(modid
, &modid
);
1296 (void) mdb_ctf_type_resolve(tgtid
, &tgtid
);
1298 if ((modkind
= mdb_ctf_type_kind(modid
)) == -1) {
1300 "couldn't determine type kind of mdb module type %s\n",
1302 return (-1); /* errno is set for us */
1304 if ((tgtkind
= mdb_ctf_type_kind(tgtid
)) == -1) {
1306 "couldn't determine type kind of %s\n", typename
);
1307 return (-1); /* errno is set for us */
1310 if ((modsz
= mdb_ctf_type_size(modid
)) == -1UL) {
1311 mdb_ctf_warn(flags
, "couldn't determine type size of "
1312 "mdb module type %s\n", mdbtypename
);
1313 return (-1); /* errno is set for us */
1315 if ((tgtsz
= mdb_ctf_type_size(tgtid
)) == -1UL) {
1316 mdb_ctf_warn(flags
, "couldn't determine size of %s (%s)\n",
1318 return (-1); /* errno is set for us */
1321 if (tgtkind
== CTF_K_POINTER
&& modkind
== CTF_K_INTEGER
&&
1322 strcmp(mdbtypename
, "uintptr_t") == 0) {
1323 /* allow them to convert a pointer to a uintptr_t */
1324 ASSERT(modsz
== tgtsz
);
1325 } else if (tgtkind
!= modkind
) {
1326 mdb_ctf_warn(flags
, "unexpected kind for type %s (%s)\n",
1328 return (set_errno(EMDB_INCOMPAT
));
1335 * Must determine if the target and module types have the same
1336 * encoding before we can copy them.
1338 if (mdb_ctf_type_encoding(tgtid
, &tgt_encoding
) != 0) {
1340 "couldn't determine encoding of type %s (%s)\n",
1342 return (-1); /* errno is set for us */
1344 if (mdb_ctf_type_encoding(modid
, &mod_encoding
) != 0) {
1345 mdb_ctf_warn(flags
, "couldn't determine encoding of "
1346 "mdb module type %s\n", mdbtypename
);
1347 return (-1); /* errno is set for us */
1350 if (modkind
== CTF_K_INTEGER
) {
1351 if ((tgt_encoding
.cte_format
& CTF_INT_SIGNED
) !=
1352 (mod_encoding
.cte_format
& CTF_INT_SIGNED
)) {
1354 "signedness mismatch between type "
1355 "%s (%s) and mdb module type %s\n",
1356 typename
, tgtname
, mdbtypename
);
1357 return (set_errno(EMDB_INCOMPAT
));
1360 ((tgt_encoding
.cte_format
& CTF_INT_SIGNED
) != 0);
1361 } else if (tgt_encoding
.cte_format
!= mod_encoding
.cte_format
) {
1363 "encoding mismatch (%#x != %#x) between type "
1364 "%s (%s) and mdb module type %s\n",
1365 tgt_encoding
.cte_format
, mod_encoding
.cte_format
,
1366 typename
, tgtname
, mdbtypename
);
1367 return (set_errno(EMDB_INCOMPAT
));
1372 * If the sizes don't match we need to be tricky to make
1373 * sure that the caller gets the correct data.
1375 if (modsz
< tgtsz
) {
1376 mdb_ctf_warn(flags
, "size of type %s (%s) is too "
1377 "large for mdb module type %s\n",
1378 typename
, tgtname
, mdbtypename
);
1379 return (set_errno(EMDB_INCOMPAT
));
1380 } else if (modsz
> tgtsz
) {
1383 * Fill modbuf with 1's for sign extension if target
1384 * buf is a signed integer and its value is negative.
1386 * S = sign bit (in most-significant byte)
1389 * +--------+--------+--------+--------+
1391 * +--------+--------+--------+--------+
1394 * LITTLE ENDIAN DATA
1395 * +--------+--------+--------+--------+
1397 * +--------+--------+--------+--------+
1402 if (signed_int
&& (tgtbuf
[0] & 0x80) != 0)
1404 if (signed_int
&& (tgtbuf
[tgtsz
- 1] & 0x80) != 0)
1406 (void) memset(modbuf
, 0xFF, modsz
);
1408 bzero(modbuf
, modsz
);
1410 bcopy(tgtbuf
, modbuf
+ modsz
- tgtsz
, tgtsz
);
1412 bcopy(tgtbuf
, modbuf
, tgtsz
);
1415 bcopy(tgtbuf
, modbuf
, modsz
);
1421 if (modsz
!= tgtsz
|| modsz
!= sizeof (int)) {
1422 mdb_ctf_warn(flags
, "unexpected size of type %s (%s)\n",
1424 return (set_errno(EMDB_INCOMPAT
));
1428 * Default to the same value as in the target.
1430 bcopy(tgtbuf
, modbuf
, sizeof (int));
1436 ev
.ev_modbuf
= (int *)modbuf
;
1437 ev
.ev_name
= mdb_ctf_enum_name(tgtid
, i
);
1438 if (ev
.ev_name
== NULL
) {
1440 "unexpected value %u of enum type %s (%s)\n",
1441 i
, typename
, tgtname
);
1442 return (set_errno(EMDB_INCOMPAT
));
1445 ret
= mdb_ctf_enum_iter(modid
, enum_cb
, &ev
);
1447 /* value not found */
1449 "unexpected value %s (%u) of enum type %s (%s)\n",
1450 ev
.ev_name
, i
, typename
, tgtname
);
1451 return (set_errno(EMDB_INCOMPAT
));
1452 } else if (ret
== 1) {
1455 } else if (ret
== -1) {
1456 mdb_ctf_warn(flags
, "could not iterate enum %s (%s)\n",
1462 mbr
.m_modbuf
= modbuf
;
1463 mbr
.m_tgtbuf
= tgtbuf
;
1464 mbr
.m_tgtid
= tgtid
;
1465 mbr
.m_flags
= flags
;
1466 mbr
.m_tgtname
= typename
;
1468 return (mdb_ctf_member_iter(modid
, member_cb
, &mbr
));
1471 mbr
.m_modbuf
= modbuf
;
1472 mbr
.m_tgtbuf
= tgtbuf
;
1473 mbr
.m_tgtid
= tgtid
;
1474 mbr
.m_flags
= flags
;
1475 mbr
.m_tgtname
= typename
;
1478 * Not all target union members need to be present in the
1479 * mdb type. If there is only a single union member in the
1480 * mdb type, its actual type does not need to match with
1481 * its target's type. On the other hand, if more than one
1482 * union members are specified in the mdb type, their types
1483 * must match with the types of their relevant union members
1484 * of the target union.
1486 mod_members
= mdb_ctf_num_members(modid
);
1487 if (mod_members
== 1) {
1488 return (mdb_ctf_member_iter(modid
, member_cb
, &mbr
));
1489 } else if (mod_members
> 1) {
1490 if (mdb_ctf_member_iter(modid
, type_equals_cb
,
1493 "inexact match for union %s (%s)\n",
1495 return (set_errno(EMDB_INCOMPAT
));
1499 * From the check above we know that the members
1500 * which are present in the mdb type are equal to
1501 * the types in the target. Thus, the member_cb
1502 * callback below will not move anything around and
1503 * it is equivalent to:
1505 * bcopy(tgtbuf, modbuf, MAX(module member's sizes))
1507 return (mdb_ctf_member_iter(modid
, member_cb
, &mbr
));
1510 * We either got 0 or -1. In any case that number
1511 * should be returned right away. For the error
1512 * case of -1, errno has been set for us.
1514 return (mod_members
);
1518 if (mdb_ctf_array_info(tgtid
, &tar
) != 0) {
1520 "couldn't get array info for %s (%s)\n",
1522 return (-1); /* errno is set for us */
1524 if (mdb_ctf_array_info(modid
, &mar
) != 0) {
1526 "couldn't get array info for mdb module type %s\n",
1528 return (-1); /* errno is set for us */
1531 if (tar
.mta_nelems
!= mar
.mta_nelems
) {
1533 "unexpected array size (%u) for type %s (%s)\n",
1534 tar
.mta_nelems
, typename
, tgtname
);
1535 return (set_errno(EMDB_INCOMPAT
));
1538 if ((modsz
= mdb_ctf_type_size(mar
.mta_contents
)) == -1UL) {
1539 mdb_ctf_warn(flags
, "couldn't determine type size of "
1540 "mdb module type %s\n", mdbtypename
);
1541 return (-1); /* errno is set for us */
1543 if ((tgtsz
= mdb_ctf_type_size(tar
.mta_contents
)) == -1UL) {
1545 "couldn't determine size of %s (%s)\n",
1547 return (-1); /* errno is set for us */
1550 for (i
= 0; i
< tar
.mta_nelems
; i
++) {
1551 ret
= vread_helper(mar
.mta_contents
, modbuf
+ i
* modsz
,
1552 tar
.mta_contents
, tgtbuf
+ i
* tgtsz
,
1562 mdb_ctf_warn(flags
, "unsupported kind %d for type %s (%s)\n",
1563 modkind
, typename
, tgtname
);
1564 return (set_errno(EMDB_INCOMPAT
));
1568 * Like mdb_vread(), mdb_ctf_vread() is used to read from the target's
1569 * virtual address space. However, mdb_ctf_vread() can be used to safely
1570 * read a complex type (e.g. a struct) from the target, even if MDB was compiled
1571 * against a different definition of that type (e.g. when debugging a crash
1572 * dump from an older release).
1574 * Callers can achieve this by defining their own type which corresponds to the
1575 * type in the target, but contains only the members that the caller requires.
1576 * Using the CTF type information embedded in the target, mdb_ctf_vread will
1577 * find the required members in the target and fill in the caller's structure.
1578 * The members are located by name, and their types are verified to be
1581 * By convention, the caller will declare a type with the name "mdb_<type>",
1582 * where <type> is the name of the type in the target (e.g. mdb_zio_t). This
1583 * type will contain the members that the caller is interested in. For example:
1585 * typedef struct mdb_zio {
1586 * enum zio_type io_type;
1587 * uintptr_t io_waiter;
1590 * uintptr_t list_next;
1597 * error = mdb_ctf_vread(&zio, "zio_t", "mdb_zio_t", zio_target_addr, 0);
1599 * If a given MDB module has different dcmds or walkers that need to read
1600 * different members from the same struct, then different "mdb_" types
1601 * should be declared for each caller. By convention, these types should
1602 * be named "mdb_<dcmd or walker>_<type>", e.g. mdb_findstack_kthread_t
1603 * for ::findstack. If the MDB module is compiled from several source files,
1604 * one must be especially careful to not define different types with the
1605 * same name in different source files, because the compiler can not detect
1608 * Enums will also be translated by name, so the mdb module will receive
1609 * the enum value it expects even if the target has renumbered the enum.
1610 * Warning: it will therefore only work with enums are only used to store
1611 * legitimate enum values (not several values or-ed together).
1613 * By default, if mdb_ctf_vread() can not find any members or enum values,
1614 * it will print a descriptive message (with mdb_warn()) and fail.
1615 * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message.
1616 * Additional flags can be used to ignore specific types of translation
1617 * failure, but should be used with caution, because they will silently leave
1618 * the caller's buffer uninitialized.
1621 mdb_ctf_vread(void *modbuf
, const char *target_typename
,
1622 const char *mdb_typename
, uintptr_t addr
, uint_t flags
)
1632 if ((mod
= mdb_get_module()) == NULL
|| (mfp
= mod
->mod_ctfp
) == NULL
) {
1633 mdb_ctf_warn(flags
, "no ctf data found for mdb module %s\n",
1635 return (set_errno(EMDB_NOCTF
));
1638 if ((mid
= ctf_lookup_by_name(mfp
, mdb_typename
)) == CTF_ERR
) {
1639 mdb_ctf_warn(flags
, "couldn't find ctf data for "
1640 "type %s in mdb module %s\n",
1641 mdb_typename
, mod
->mod_name
);
1642 return (set_errno(ctf_to_errno(ctf_errno(mfp
))));
1645 set_ctf_id(&modid
, mfp
, mid
);
1647 if (mdb_ctf_lookup_by_name(target_typename
, &tgtid
) != 0) {
1649 "couldn't find type %s in target's ctf data\n",
1651 return (set_errno(EMDB_NOCTF
));
1655 * Read the data out of the target's address space.
1657 if ((size
= mdb_ctf_type_size(tgtid
)) == -1UL) {
1658 mdb_ctf_warn(flags
, "couldn't determine size of type %s\n",
1660 return (-1); /* errno is set for us */
1663 tgtbuf
= mdb_alloc(size
, UM_SLEEP
| UM_GC
);
1665 if (mdb_vread(tgtbuf
, size
, addr
) < 0) {
1666 mdb_ctf_warn(flags
, "couldn't read %s from %p\n",
1667 target_typename
, addr
);
1668 return (-1); /* errno is set for us */
1671 return (vread_helper(modid
, modbuf
, tgtid
, tgtbuf
, NULL
, flags
));
1675 * Note: mdb_ctf_readsym() doesn't take separate parameters for the name
1676 * of the target's type vs the mdb module's type. Use with complicated
1677 * types (e.g. structs) may result in unnecessary failure if a member of
1678 * the struct has been changed in the target, but is not actually needed
1679 * by the mdb module. Use mdb_lookup_by_name() + mdb_ctf_vread() to
1680 * avoid this problem.
1683 mdb_ctf_readsym(void *buf
, const char *typename
, const char *name
, uint_t flags
)
1687 if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY
, name
, &sym
) != 0) {
1688 mdb_ctf_warn(flags
, "couldn't find symbol %s\n", name
);
1689 return (-1); /* errno is set for us */
1692 return (mdb_ctf_vread(buf
, typename
, typename
, sym
.st_value
, flags
));
1696 mdb_ctf_bufopen(const void *ctf_va
, size_t ctf_size
, const void *sym_va
,
1697 Shdr
*symhdr
, const void *str_va
, Shdr
*strhdr
, int *errp
)
1699 ctf_sect_t ctdata
, symtab
, strtab
;
1701 ctdata
.cts_name
= ".SUNW_ctf";
1702 ctdata
.cts_type
= SHT_PROGBITS
;
1703 ctdata
.cts_flags
= 0;
1704 ctdata
.cts_data
= ctf_va
;
1705 ctdata
.cts_size
= ctf_size
;
1706 ctdata
.cts_entsize
= 1;
1707 ctdata
.cts_offset
= 0;
1709 symtab
.cts_name
= ".symtab";
1710 symtab
.cts_type
= symhdr
->sh_type
;
1711 symtab
.cts_flags
= symhdr
->sh_flags
;
1712 symtab
.cts_data
= sym_va
;
1713 symtab
.cts_size
= symhdr
->sh_size
;
1714 symtab
.cts_entsize
= symhdr
->sh_entsize
;
1715 symtab
.cts_offset
= symhdr
->sh_offset
;
1717 strtab
.cts_name
= ".strtab";
1718 strtab
.cts_type
= strhdr
->sh_type
;
1719 strtab
.cts_flags
= strhdr
->sh_flags
;
1720 strtab
.cts_data
= str_va
;
1721 strtab
.cts_size
= strhdr
->sh_size
;
1722 strtab
.cts_entsize
= strhdr
->sh_entsize
;
1723 strtab
.cts_offset
= strhdr
->sh_offset
;
1725 return (ctf_bufopen(&ctdata
, &symtab
, &strtab
, errp
));
1729 mdb_ctf_synthetics_init(void)
1733 if ((mdb
.m_synth
= ctf_create(&err
)) == NULL
)
1734 return (set_errno(ctf_to_errno(err
)));
1740 mdb_ctf_synthetics_fini(void)
1742 if (mdb
.m_synth
== NULL
)
1745 ctf_close(mdb
.m_synth
);
1750 mdb_ctf_synthetics_create_base(int kind
)
1752 const synth_intrinsic_t
*synp
;
1753 const synth_typedef_t
*sytp
;
1756 ctf_file_t
*cp
= mdb
.m_synth
;
1758 if (mdb
.m_synth
== NULL
) {
1759 mdb_printf("synthetic types disabled: ctf create failed\n");
1764 case SYNTHETIC_ILP32
:
1765 synp
= synth_builtins32
;
1766 sytp
= synth_typedefs32
;
1768 case SYNTHETIC_LP64
:
1769 synp
= synth_builtins64
;
1770 sytp
= synth_typedefs64
;
1773 mdb_dprintf(MDB_DBG_CTF
, "invalid type of intrinsic: %d\n",
1779 for (; synp
->syn_name
!= NULL
; synp
++) {
1780 if (synp
->syn_kind
== CTF_K_INTEGER
) {
1781 err
= ctf_add_integer(cp
, CTF_ADD_ROOT
, synp
->syn_name
,
1784 err
= ctf_add_float(cp
, CTF_ADD_ROOT
, synp
->syn_name
,
1788 if (err
== CTF_ERR
) {
1789 mdb_dprintf(MDB_DBG_CTF
, "couldn't add synthetic "
1790 "type: %s\n", synp
->syn_name
);
1795 if (ctf_update(cp
) == CTF_ERR
) {
1796 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
1800 for (; sytp
->syt_src
!= NULL
; sytp
++) {
1801 id
= ctf_lookup_by_name(cp
, sytp
->syt_src
);
1802 if (id
== CTF_ERR
) {
1803 mdb_dprintf(MDB_DBG_CTF
, "cailed to lookup %s: %s\n",
1804 sytp
->syt_src
, ctf_errmsg(ctf_errno(cp
)));
1807 if (ctf_add_typedef(cp
, CTF_ADD_ROOT
, sytp
->syt_targ
, id
) ==
1809 mdb_dprintf(MDB_DBG_CTF
, "couldn't add typedef %s "
1810 "%s: %s\n", sytp
->syt_targ
, sytp
->syt_src
,
1811 ctf_errmsg(ctf_errno(cp
)));
1816 if (ctf_update(cp
) == CTF_ERR
) {
1817 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
1824 err
= set_errno(ctf_to_errno(ctf_errno(cp
)));
1825 (void) ctf_discard(cp
);
1830 mdb_ctf_synthetics_reset(void)
1832 mdb_ctf_synthetics_fini();
1833 return (mdb_ctf_synthetics_init());
1837 mdb_ctf_add_typedef(const char *name
, const mdb_ctf_id_t
*p
, mdb_ctf_id_t
*new)
1841 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
1843 if (mdb
.m_synth
== NULL
) {
1844 mdb_printf("synthetic types disabled: ctf create failed\n");
1848 if (mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1849 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1850 "with that name already exists\n", name
);
1851 return (set_errno(EEXIST
));
1854 rid
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
1855 if (rid
== CTF_ERR
) {
1856 mdb_dprintf(MDB_DBG_CTF
, "failed to add reference type: %s\n",
1857 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1858 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1860 rid
= ctf_add_typedef(mdb
.m_synth
, CTF_ADD_ROOT
, name
, rid
);
1861 if (rid
== CTF_ERR
) {
1862 mdb_dprintf(MDB_DBG_CTF
, "failed to add typedef: %s",
1863 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1864 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1867 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1868 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1869 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1870 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1874 set_ctf_id(new, mdb
.m_synth
, rid
);
1880 mdb_ctf_add_struct(const char *name
, mdb_ctf_id_t
*rid
)
1885 if (mdb
.m_synth
== NULL
) {
1886 mdb_printf("synthetic types disabled: ctf create failed\n");
1890 if (name
!= NULL
&& mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1891 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1892 "with that name already exists\n", name
);
1893 return (set_errno(EEXIST
));
1896 if ((id
= ctf_add_struct(mdb
.m_synth
, CTF_ADD_ROOT
, name
)) ==
1898 mdb_dprintf(MDB_DBG_CTF
, "failed to add struct: %s\n",
1899 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1900 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1903 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1904 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1905 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1906 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1910 set_ctf_id(rid
, mdb
.m_synth
, id
);
1916 mdb_ctf_add_union(const char *name
, mdb_ctf_id_t
*rid
)
1921 if (mdb
.m_synth
== NULL
) {
1922 mdb_printf("synthetic types disabled: ctf create failed\n");
1926 if (name
!= NULL
&& mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1927 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1928 "with that name already exists\n", name
);
1929 return (set_errno(EEXIST
));
1932 if ((id
= ctf_add_union(mdb
.m_synth
, CTF_ADD_ROOT
, name
)) ==
1934 mdb_dprintf(MDB_DBG_CTF
, "failed to add union: %s\n",
1935 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1936 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1939 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1940 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1941 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1942 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1946 set_ctf_id(rid
, mdb
.m_synth
, id
);
1952 mdb_ctf_add_member(const mdb_ctf_id_t
*p
, const char *name
,
1953 const mdb_ctf_id_t
*mtype
, mdb_ctf_id_t
*rid
)
1956 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
1957 mdb_ctf_impl_t
*mcim
= (mdb_ctf_impl_t
*)mtype
;
1959 if (mdb
.m_synth
== NULL
) {
1960 mdb_printf("synthetic types disabled: ctf create failed\n");
1964 if (mcip
->mci_fp
!= mdb
.m_synth
) {
1965 mdb_dprintf(MDB_DBG_CTF
, "requested to add member to a type "
1966 "that wasn't created from a synthetic\n");
1967 return (set_errno(EINVAL
));
1970 mtid
= ctf_add_type(mdb
.m_synth
, mcim
->mci_fp
, mcim
->mci_id
);
1971 if (mtid
== CTF_ERR
) {
1972 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
1973 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1974 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1977 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1978 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1979 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1980 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1983 id
= ctf_add_member(mdb
.m_synth
, mcip
->mci_id
, name
, mtid
);
1984 if (id
== CTF_ERR
) {
1985 mdb_dprintf(MDB_DBG_CTF
, "failed to add member %s: %s\n",
1986 name
, ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1987 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1990 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1991 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1992 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1993 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1997 set_ctf_id(rid
, mdb
.m_synth
, id
);
2003 mdb_ctf_add_array(const mdb_ctf_arinfo_t
*marp
, mdb_ctf_id_t
*rid
)
2005 mdb_ctf_impl_t
*mcip
;
2009 if (mdb
.m_synth
== NULL
) {
2010 mdb_printf("synthetic types disabled: ctf create failed\n");
2014 car
.ctr_nelems
= marp
->mta_nelems
;
2016 mcip
= (mdb_ctf_impl_t
*)&marp
->mta_contents
;
2017 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
2018 if (id
== CTF_ERR
) {
2019 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
2020 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2021 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2023 car
.ctr_contents
= id
;
2025 mcip
= (mdb_ctf_impl_t
*)&marp
->mta_index
;
2026 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
2027 if (id
== CTF_ERR
) {
2028 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
2029 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2030 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2034 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2035 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2036 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2037 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2040 id
= ctf_add_array(mdb
.m_synth
, CTF_ADD_ROOT
, &car
);
2041 if (id
== CTF_ERR
) {
2042 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2043 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2044 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2047 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2048 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2049 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2050 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2054 set_ctf_id(rid
, mdb
.m_synth
, id
);
2060 mdb_ctf_add_pointer(const mdb_ctf_id_t
*p
, mdb_ctf_id_t
*rid
)
2063 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
2065 if (mdb
.m_synth
== NULL
) {
2066 mdb_printf("synthetic types disabled: ctf create failed\n");
2070 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
2071 if (id
== CTF_ERR
) {
2072 mdb_dprintf(MDB_DBG_CTF
, "failed to add pointer type: %s\n",
2073 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2074 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2077 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2078 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2079 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2080 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2084 id
= ctf_add_pointer(mdb
.m_synth
, CTF_ADD_ROOT
, id
);
2085 if (id
== CTF_ERR
) {
2086 mdb_dprintf(MDB_DBG_CTF
, "failed to add pointer: %s\n",
2087 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2088 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2091 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2092 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2093 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2094 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2099 set_ctf_id(rid
, mdb
.m_synth
, id
);
2105 mdb_ctf_type_delete(const mdb_ctf_id_t
*id
)
2109 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)id
;
2111 if (mcip
->mci_fp
!= mdb
.m_synth
) {
2112 mdb_warn("bad ctf_file_t, expected synth container\n");
2116 ret
= ctf_delete_type(mcip
->mci_fp
, mcip
->mci_id
);
2118 mdb_dprintf(MDB_DBG_CTF
, "failed to delete synthetic type: %s",
2119 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2120 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2123 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2124 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2125 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2126 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2133 mdb_ctf_synthetics_file_cb(mdb_ctf_id_t id
, void *arg
)
2135 ctf_file_t
*targ
= arg
;
2136 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)&id
;
2138 if (ctf_add_type(targ
, mcip
->mci_fp
, mcip
->mci_id
) == CTF_ERR
) {
2139 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %d: %s\n",
2140 mcip
->mci_id
, ctf_errmsg(ctf_errno(mcip
->mci_fp
)));
2141 return (set_errno(ctf_to_errno(ctf_errno(mcip
->mci_fp
))));
2148 mdb_ctf_synthetics_from_file(const char *file
)
2150 ctf_file_t
*fp
, *syn
= mdb
.m_synth
;
2155 mdb_warn("synthetic types disabled: ctf create failed\n");
2159 if ((fp
= mdb_ctf_open(file
, &ret
)) == NULL
) {
2160 mdb_warn("failed to parse ctf data in %s: %s\n", file
,
2168 ti
.ti_cb
= mdb_ctf_synthetics_file_cb
;
2169 if (ctf_type_iter(fp
, type_iter_cb
, &ti
) == CTF_ERR
) {
2170 ret
= set_errno(ctf_to_errno(ctf_errno(fp
)));
2171 mdb_warn("failed to add types");
2175 if (ctf_update(syn
) == CTF_ERR
) {
2176 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
2177 ret
= set_errno(ctf_to_errno(ctf_errno(fp
)));
2183 (void) ctf_discard(syn
);
2188 mdb_ctf_synthetics_to_file(const char *file
)
2191 ctf_file_t
*fp
= mdb
.m_synth
;
2194 mdb_warn("synthetic types are disabled, not writing "
2199 err
= mdb_ctf_write(file
, fp
);
2202 (void) set_errno(ctf_to_errno(ctf_errno(fp
)));
2204 (void) set_errno(err
);