aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c')
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c98
1 files changed, 70 insertions, 28 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index f028f99ccf64..8cc504856567 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -1131,6 +1131,29 @@ dt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp,
rp_is_void = ctf_type_encoding(rfp, rref, &e) == 0 && IS_VOID(e);
/*
+ * Let a pointer to a forward declaration be compatible with a pointer
+ * to a struct or union of the same name.
+ */
+ if (lkind == CTF_K_POINTER && rkind == CTF_K_POINTER) {
+ int lrkind, rrkind;
+
+ lrkind = ctf_type_kind(lfp, lref);
+ rrkind = ctf_type_kind(rfp, rref);
+ if (lrkind == CTF_K_FORWARD || rrkind == CTF_K_FORWARD) {
+ const char *lname, *rname;
+ char ln[DT_TYPE_NAMELEN], rn[DT_TYPE_NAMELEN];
+
+ lname = ctf_type_name(lfp, lref, ln, sizeof (ln));
+ rname = ctf_type_name(rfp, rref, rn, sizeof (rn));
+ if (lname != NULL && rname != NULL &&
+ strcmp(lname, rname) == 0) {
+ lp_is_void = lrkind == CTF_K_FORWARD;
+ rp_is_void = rrkind == CTF_K_FORWARD;
+ }
+ }
+ }
+
+ /*
* The types are compatible if both are pointers to the same type, or
* if either pointer is a void pointer. If they are compatible, set
* tp to point to the more specific pointer type and return it.
@@ -1895,6 +1918,14 @@ dt_node_op1(int op, dt_node_t *cp)
return (cp);
}
+ /*
+ * When applying the addressof operator to an identifier, it's okay if
+ * we can't find type information for the identifier, so flag the node
+ * to ensure that we don't raise an error.
+ */
+ if (op == DT_TOK_ADDROF && cp->dn_kind == DT_NODE_IDENT)
+ cp->dn_flags |= DT_NF_IDENTADDR;
+
dnp = dt_node_alloc(DT_NODE_OP1);
assert(op <= USHRT_MAX);
dnp->dn_op = (ushort_t)op;
@@ -2763,10 +2794,21 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
dt_module_modelname(dtp->dt_ddefs));
}
- xyerror(D_SYM_NOTYPES,
+ /*
+ * If we're taking the address of an identifier that
+ * doesn't have type info, try to make it a void *.
+ * This lets us use identifiers that are defined in
+ * assembly and don't have type information.
+ */
+ if ((dnp->dn_flags & DT_NF_IDENTADDR) == 0 ||
+ dtrace_lookup_by_type(dtp, DTRACE_OBJ_CDEFS,
+ "void", &dtt) != 0) {
+ xyerror(D_SYM_NOTYPES,
"no symbolic type information is available for "
- "%s%s%s: %s\n", dts.dts_object, mark, dts.dts_name,
- dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ "%s%s%s: %s\n", dts.dts_object, mark,
+ dts.dts_name,
+ dtrace_errmsg(dtp, dtrace_errno(dtp)));
+ }
}
idp = dt_ident_create(name, DT_IDENT_SYMBOL, 0, 0,
@@ -4483,30 +4525,30 @@ dt_cook_none(dt_node_t *dnp, uint_t idflags)
return (dnp);
}
-static dt_node_t *(*dt_cook_funcs[])(dt_node_t *, uint_t) = {
- dt_cook_none, /* DT_NODE_FREE */
- dt_cook_none, /* DT_NODE_INT */
- dt_cook_none, /* DT_NODE_STRING */
- dt_cook_ident, /* DT_NODE_IDENT */
- dt_cook_var, /* DT_NODE_VAR */
- dt_cook_none, /* DT_NODE_SYM */
- dt_cook_none, /* DT_NODE_TYPE */
- dt_cook_func, /* DT_NODE_FUNC */
- dt_cook_op1, /* DT_NODE_OP1 */
- dt_cook_op2, /* DT_NODE_OP2 */
- dt_cook_op3, /* DT_NODE_OP3 */
- dt_cook_statement, /* DT_NODE_DEXPR */
- dt_cook_statement, /* DT_NODE_DFUNC */
- dt_cook_aggregation, /* DT_NODE_AGG */
- dt_cook_none, /* DT_NODE_PDESC */
- dt_cook_clause, /* DT_NODE_CLAUSE */
- dt_cook_inline, /* DT_NODE_INLINE */
- dt_cook_member, /* DT_NODE_MEMBER */
- dt_cook_xlator, /* DT_NODE_XLATOR */
- dt_cook_none, /* DT_NODE_PROBE */
- dt_cook_provider, /* DT_NODE_PROVIDER */
- dt_cook_none, /* DT_NODE_PROG */
- dt_cook_none, /* DT_NODE_IF */
+static dt_node_t *(* const dt_cook_funcs[])(dt_node_t *, uint_t) = {
+ [DT_NODE_FREE] = dt_cook_none,
+ [DT_NODE_INT] = dt_cook_none,
+ [DT_NODE_STRING] = dt_cook_none,
+ [DT_NODE_IDENT] = dt_cook_ident,
+ [DT_NODE_VAR] = dt_cook_var,
+ [DT_NODE_SYM] = dt_cook_none,
+ [DT_NODE_TYPE] = dt_cook_none,
+ [DT_NODE_FUNC] = dt_cook_func,
+ [DT_NODE_OP1] = dt_cook_op1,
+ [DT_NODE_OP2] = dt_cook_op2,
+ [DT_NODE_OP3] = dt_cook_op3,
+ [DT_NODE_DEXPR] = dt_cook_statement,
+ [DT_NODE_DFUNC] = dt_cook_statement,
+ [DT_NODE_AGG] = dt_cook_aggregation,
+ [DT_NODE_PDESC] = dt_cook_none,
+ [DT_NODE_CLAUSE] = dt_cook_clause,
+ [DT_NODE_INLINE] = dt_cook_inline,
+ [DT_NODE_MEMBER] = dt_cook_member,
+ [DT_NODE_XLATOR] = dt_cook_xlator,
+ [DT_NODE_PROBE] = dt_cook_none,
+ [DT_NODE_PROVIDER] = dt_cook_provider,
+ [DT_NODE_PROG] = dt_cook_none,
+ [DT_NODE_IF] = dt_cook_none,
};
/*
@@ -4767,8 +4809,8 @@ dt_printd(dt_node_t *dnp, FILE *fp, int depth)
dt_printd(dnp->dn_pred, fp, 0);
(void) fprintf(fp, "/\n");
}
- (void) fprintf(fp, "{\n");
+ (void) fprintf(fp, "{\n");
for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
dt_printd(arg, fp, depth + 1);
(void) fprintf(fp, "}\n");