summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdtrace/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdtrace/common')
-rw-r--r--usr/src/lib/libdtrace/common/dt_cg.c50
-rw-r--r--usr/src/lib/libdtrace/common/dt_dis.c20
-rw-r--r--usr/src/lib/libdtrace/common/dt_open.c6
3 files changed, 54 insertions, 22 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_cg.c b/usr/src/lib/libdtrace/common/dt_cg.c
index 28db9b2262..9f3625e6ee 100644
--- a/usr/src/lib/libdtrace/common/dt_cg.c
+++ b/usr/src/lib/libdtrace/common/dt_cg.c
@@ -27,6 +27,7 @@
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
*/
#include <sys/types.h>
@@ -1115,23 +1116,14 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
/*
- * If we are storing to a variable, generate an stv instruction from
- * the variable specified by the identifier. If we are storing to a
- * memory address, generate code again for the left-hand side using
- * DT_NF_REF to get the address, and then generate a store to it.
- * In both paths, we assume dnp->dn_reg already has the new value.
+ * If we are storing to a memory address, generate code again for the
+ * left-hand side using DT_NF_REF to get the address, and then generate
+ * a store to it.
+ *
+ * Both here and the other variable-store paths, we assume dnp->dn_reg
+ * already has the new value.
*/
- if (dnp->dn_left->dn_kind == DT_NODE_VAR) {
- idp = dt_ident_resolve(dnp->dn_left->dn_ident);
-
- if (idp->di_kind == DT_IDENT_ARRAY)
- dt_cg_arglist(idp, dnp->dn_left->dn_args, dlp, drp);
-
- idp->di_flags |= DT_IDFLG_DIFW;
- instr = DIF_INSTR_STV(dt_cg_stvar(idp),
- idp->di_id, dnp->dn_reg);
- dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- } else {
+ if (dnp->dn_left->dn_kind != DT_NODE_VAR) {
uint_t rbit = dnp->dn_left->dn_flags & DT_NF_REF;
assert(dnp->dn_left->dn_flags & DT_NF_WRITABLE);
@@ -1145,7 +1137,33 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dnp->dn_left->dn_flags &= ~DT_NF_REF;
dnp->dn_left->dn_flags |= rbit;
+ return;
}
+
+ idp = dt_ident_resolve(dnp->dn_left->dn_ident);
+ idp->di_flags |= DT_IDFLG_DIFW;
+
+ /*
+ * Storing to an array variable is a special case.
+ * Only 'uregs[]' supports this for the time being.
+ */
+ if (idp->di_kind == DT_IDENT_ARRAY &&
+ idp->di_id <= DIF_VAR_ARRAY_MAX) {
+ dt_node_t *idx = dnp->dn_left->dn_args;
+
+ dt_cg_node(idx, dlp, drp);
+ instr = DIF_INSTR_FMT(DIF_OP_STGA, idp->di_id, idx->dn_reg,
+ dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, idx->dn_reg);
+ return;
+ }
+
+ if (idp->di_kind == DT_IDENT_ARRAY)
+ dt_cg_arglist(idp, dnp->dn_left->dn_args, dlp, drp);
+
+ instr = DIF_INSTR_STV(dt_cg_stvar(idp), idp->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
}
static void
diff --git a/usr/src/lib/libdtrace/common/dt_dis.c b/usr/src/lib/libdtrace/common/dt_dis.c
index c0af36420e..60195f3970 100644
--- a/usr/src/lib/libdtrace/common/dt_dis.c
+++ b/usr/src/lib/libdtrace/common/dt_dis.c
@@ -27,7 +27,7 @@
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
- * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017 Joyent, Inc.
*/
#include <strings.h>
@@ -47,7 +47,7 @@ dt_dis_log(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
/*ARGSUSED*/
static void
dt_dis_branch(const dtrace_difo_t *dp, const char *name,
- dif_instr_t in, FILE *fp)
+ dif_instr_t in, FILE *fp)
{
(void) fprintf(fp, "%-4s %u", name, DIF_INSTR_LABEL(in));
}
@@ -63,7 +63,7 @@ dt_dis_load(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
/*ARGSUSED*/
static void
dt_dis_store(const dtrace_difo_t *dp, const char *name,
- dif_instr_t in, FILE *fp)
+ dif_instr_t in, FILE *fp)
{
(void) fprintf(fp, "%-4s %%r%u, [%%r%u]", name,
DIF_INSTR_R1(in), DIF_INSTR_RD(in));
@@ -167,6 +167,19 @@ dt_dis_stv(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
}
static void
+dt_dis_sta(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t var = DIF_INSTR_VAR(in);
+ const char *vname;
+
+ (void) fprintf(fp, "%-4s DT_VAR(%u), %%r%u, %%r%u",
+ name, var, DIF_INSTR_R2(in), DIF_INSTR_RD(in));
+
+ if ((vname = dt_dis_varname(dp, var, dt_dis_scope(name))) != NULL)
+ (void) fprintf(fp, "\t\t! DT_VAR(%u) = \"%s\"", var, vname);
+}
+
+static void
dt_dis_setx(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
{
uint_t intptr = DIF_INSTR_INTEGER(in);
@@ -428,6 +441,7 @@ dt_dis(const dtrace_difo_t *dp, FILE *fp)
{ "rldx", dt_dis_load }, /* DIF_OP_RLDX */
{ "xlate", dt_dis_xlate }, /* DIF_OP_XLATE */
{ "xlarg", dt_dis_xlate }, /* DIF_OP_XLARG */
+ { "stga", dt_dis_sta }, /* DIF_OP_XLARG */
};
const struct opent *op;
diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c
index 38c8146039..d6e90bd953 100644
--- a/usr/src/lib/libdtrace/common/dt_open.c
+++ b/usr/src/lib/libdtrace/common/dt_open.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
@@ -427,8 +427,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_type, "uid_t" },
{ "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
-{ "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
- &dt_idops_regs, NULL },
+{ "uregs", DT_IDENT_ARRAY, DT_IDFLG_WRITE, DIF_VAR_UREGS, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_regs, NULL },
{ "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "stack(...)" },
{ "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,