Print this page
libdtrace: attempt to resolve FORWARD types to concrete types
1730 DTrace should ignore type information from modules with cth_parlabel mismatches
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
@@ -841,10 +841,21 @@
if (pmp == NULL)
(void) dt_set_errno(dtp, EDT_NOMEM);
goto err;
}
+ /*
+ * If the label we claim the parent must have is not actually
+ * present in the parent module, ignore the CTF entirely
+ * rather than acquiring possibly bad type references.
+ */
+ if (ctf_label_info(pfp, ctf_parent_label(dmp->dm_ctfp),
+ NULL) == CTF_ERR) {
+ (void) dt_set_errno(dtp, EDT_BADCTF);
+ goto err;
+ }
+
if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
(void) dt_set_errno(dtp, EDT_CTF);
goto err;
}
@@ -854,10 +865,12 @@
dmp->dm_name, (void *)dmp->dm_ctfp);
return (dmp->dm_ctfp);
err:
+ dt_dprintf("could not load CTF container for %s: %s\n",
+ dmp->dm_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
ctf_close(dmp->dm_ctfp);
dmp->dm_ctfp = NULL;
return (NULL);
}
@@ -1370,10 +1383,43 @@
}
return (0);
}
+boolean_t
+dt_is_forward_decl(ctf_file_t *file, ctf_id_t type)
+{
+ ctf_id_t kind = ctf_type_kind(file, type);
+
+ while ((type = ctf_type_reference(file, type)) != CTF_ERR) {
+ type = ctf_type_resolve(file, type);
+ kind = ctf_type_kind(file, type);
+ }
+
+ return (kind == CTF_K_FORWARD);
+}
+
+void
+dt_resolve_forward_decl(ctf_file_t **ctfp, ctf_id_t *type)
+{
+ char name[DT_TYPE_NAMELEN];
+
+ while (dt_is_forward_decl(*ctfp, *type)) {
+ char *tag = ctf_type_name(*ctfp, *type, name, sizeof (name));
+ dtrace_typeinfo_t dtt;
+
+ if (tag != NULL && dt_type_lookup(tag, &dtt) == 0 &&
+ (dtt.dtt_ctfp != *ctfp) || dtt.dtt_type != *type) {
+ *ctfp = dtt.dtt_ctfp;
+ *type = dtt.dtt_type;
+ } else {
+ /* All we have is the forward definition */
+ break;
+ }
+ }
+}
+
int
dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
dtrace_typeinfo_t *tip)
{
dtrace_typeinfo_t ti;
@@ -1461,12 +1507,11 @@
}
if (id != CTF_ERR) {
tip->dtt_object = dmp->dm_name;
tip->dtt_ctfp = fp;
tip->dtt_type = id;
- if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
- CTF_K_FORWARD)
+ if (!dt_is_forward_decl(fp, ctf_type_resolve(fp, id)))
return (0);
found++;
}
}