summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2017-08-14 23:17:17 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2017-08-14 23:17:17 +0000
commit6ce9515e507bc9c47fd127589ef8734a84fed1c3 (patch)
tree81bdb54c1bdbe50f81daa194ccf9dd5b66916ec3 /usr/src/uts
parent801699355dea5fb4658b631b388aea1c1ca1926d (diff)
downloadillumos-joyent-6ce9515e507bc9c47fd127589ef8734a84fed1c3.tar.gz
OS-6066 want writable uregs[] in dtrace
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Alex Wilson <alex.wilson@joyent.com> Reviewed by: Bryan Cantrill <bryan@joyent.com> Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/dtrace/dtrace.c55
-rw-r--r--usr/src/uts/common/sys/dtrace.h3
-rw-r--r--usr/src/uts/common/sys/dtrace_impl.h3
-rw-r--r--usr/src/uts/intel/dtrace/dtrace_isa.c151
-rw-r--r--usr/src/uts/sparc/dtrace/dtrace_isa.c11
5 files changed, 195 insertions, 28 deletions
diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c
index 6ec6c5ae9d..f5ce5608aa 100644
--- a/usr/src/uts/common/dtrace/dtrace.c
+++ b/usr/src/uts/common/dtrace/dtrace.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
*/
@@ -3545,6 +3545,34 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
}
}
+static void
+dtrace_dif_variable_write(dtrace_mstate_t *mstate, dtrace_state_t *state,
+ uint64_t v, uint64_t ndx, uint64_t data)
+{
+ switch (v) {
+ case DIF_VAR_UREGS: {
+ klwp_t *lwp;
+
+ if (dtrace_destructive_disallow ||
+ !dtrace_priv_proc_control(state, mstate)) {
+ return;
+ }
+
+ if ((lwp = curthread->t_lwp) == NULL) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+ cpu_core[CPU->cpu_id].cpuc_dtrace_illval = NULL;
+ return;
+ }
+
+ dtrace_setreg(lwp->lwp_regs, ndx, data);
+ return;
+ }
+
+ default:
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return;
+ }
+}
typedef enum dtrace_json_state {
DTRACE_JSON_REST = 1,
@@ -6024,6 +6052,11 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
regs[rd] = dtrace_dif_variable(mstate, state, id, 0);
break;
+ case DIF_OP_STGA:
+ dtrace_dif_variable_write(mstate, state, r1, regs[r2],
+ regs[rd]);
+ break;
+
case DIF_OP_STGS:
id = DIF_INSTR_VAR(instr);
@@ -9407,6 +9440,15 @@ dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs,
if (rd == 0)
err += efunc(pc, "cannot write to %r0\n");
break;
+ case DIF_OP_STGA:
+ if (r1 > DIF_VAR_ARRAY_MAX)
+ err += efunc(pc, "invalid array %u\n", r1);
+ if (r2 >= nregs)
+ err += efunc(pc, "invalid register %u\n", r2);
+ if (rd >= nregs)
+ err += efunc(pc, "invalid register %u\n", rd);
+ dp->dtdo_destructive = 1;
+ break;
case DIF_OP_LDGS:
case DIF_OP_LDTS:
case DIF_OP_LDLS:
@@ -9752,12 +9794,23 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp)
break;
case DIF_OP_LDTA:
+ if (v < DIF_VAR_OTHER_UBASE) {
+ err += efunc(pc, "illegal variable load\n");
+ break;
+ }
+ /* FALLTHROUGH */
case DIF_OP_LDTS:
case DIF_OP_LDGAA:
case DIF_OP_LDTAA:
err += efunc(pc, "illegal dynamic variable load\n");
break;
+ case DIF_OP_STGA:
+ if (v < DIF_VAR_OTHER_UBASE) {
+ err += efunc(pc, "illegal variable store\n");
+ break;
+ }
+ /* FALLTHROUGH */
case DIF_OP_STTS:
case DIF_OP_STGAA:
case DIF_OP_STTAA:
diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h
index 4ee1a94510..44ca7d8ae7 100644
--- a/usr/src/uts/common/sys/dtrace.h
+++ b/usr/src/uts/common/sys/dtrace.h
@@ -25,7 +25,7 @@
*/
/*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
@@ -189,6 +189,7 @@ typedef enum dtrace_probespec {
#define DIF_OP_RLDX 77 /* rldx [r1], rd */
#define DIF_OP_XLATE 78 /* xlate xlrindex, rd */
#define DIF_OP_XLARG 79 /* xlarg xlrindex, rd */
+#define DIF_OP_STGA 80 /* stga var, ri, rd */
#define DIF_INTOFF_MAX 0xffff /* highest integer table offset */
#define DIF_STROFF_MAX 0xffff /* highest string table offset */
diff --git a/usr/src/uts/common/sys/dtrace_impl.h b/usr/src/uts/common/sys/dtrace_impl.h
index de7d0d25fb..a55d0d7e1f 100644
--- a/usr/src/uts/common/sys/dtrace_impl.h
+++ b/usr/src/uts/common/sys/dtrace_impl.h
@@ -25,7 +25,7 @@
*/
/*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -1262,6 +1262,7 @@ extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t,
volatile uint16_t *);
extern void dtrace_getpcstack(pc_t *, int, int, uint32_t *);
extern ulong_t dtrace_getreg(struct regs *, uint_t);
+extern void dtrace_setreg(struct regs *, uint_t, ulong_t);
extern uint64_t dtrace_getvmreg(uint_t, volatile uint16_t *);
extern int dtrace_getstackdepth(int);
extern void dtrace_getupcstack(uint64_t *, int);
diff --git a/usr/src/uts/intel/dtrace/dtrace_isa.c b/usr/src/uts/intel/dtrace/dtrace_isa.c
index f649473dfb..f52180b0c0 100644
--- a/usr/src/uts/intel/dtrace/dtrace_isa.c
+++ b/usr/src/uts/intel/dtrace/dtrace_isa.c
@@ -26,6 +26,7 @@
/*
* Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2017 Joyent, Inc.
*/
#include <sys/dtrace_impl.h>
@@ -546,39 +547,42 @@ dtrace_getstackdepth(int aframes)
return (depth - aframes);
}
+#if defined(__amd64)
+static const int dtrace_regmap[] = {
+ REG_GS, /* GS */
+ REG_FS, /* FS */
+ REG_ES, /* ES */
+ REG_DS, /* DS */
+ REG_RDI, /* EDI */
+ REG_RSI, /* ESI */
+ REG_RBP, /* EBP */
+ REG_RSP, /* ESP */
+ REG_RBX, /* EBX */
+ REG_RDX, /* EDX */
+ REG_RCX, /* ECX */
+ REG_RAX, /* EAX */
+ REG_TRAPNO, /* TRAPNO */
+ REG_ERR, /* ERR */
+ REG_RIP, /* EIP */
+ REG_CS, /* CS */
+ REG_RFL, /* EFL */
+ REG_RSP, /* UESP */
+ REG_SS /* SS */
+};
+#endif
+
+
ulong_t
dtrace_getreg(struct regs *rp, uint_t reg)
{
#if defined(__amd64)
- int regmap[] = {
- REG_GS, /* GS */
- REG_FS, /* FS */
- REG_ES, /* ES */
- REG_DS, /* DS */
- REG_RDI, /* EDI */
- REG_RSI, /* ESI */
- REG_RBP, /* EBP */
- REG_RSP, /* ESP */
- REG_RBX, /* EBX */
- REG_RDX, /* EDX */
- REG_RCX, /* ECX */
- REG_RAX, /* EAX */
- REG_TRAPNO, /* TRAPNO */
- REG_ERR, /* ERR */
- REG_RIP, /* EIP */
- REG_CS, /* CS */
- REG_RFL, /* EFL */
- REG_RSP, /* UESP */
- REG_SS /* SS */
- };
-
if (reg <= SS) {
- if (reg >= sizeof (regmap) / sizeof (int)) {
+ if (reg >= sizeof (dtrace_regmap) / sizeof (int)) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
return (0);
}
- reg = regmap[reg];
+ reg = dtrace_regmap[reg];
} else {
reg -= SS + 1;
}
@@ -651,6 +655,105 @@ dtrace_getreg(struct regs *rp, uint_t reg)
#endif
}
+void
+dtrace_setreg(struct regs *rp, uint_t reg, ulong_t val)
+{
+#if defined(__amd64)
+ if (reg <= SS) {
+ ASSERT(reg < (sizeof (dtrace_regmap) / sizeof (int)));
+
+ reg = dtrace_regmap[reg];
+ } else {
+ reg -= SS + 1;
+ }
+
+ switch (reg) {
+ case REG_RDI:
+ rp->r_rdi = val;
+ break;
+ case REG_RSI:
+ rp->r_rsi = val;
+ break;
+ case REG_RDX:
+ rp->r_rdx = val;
+ break;
+ case REG_RCX:
+ rp->r_rcx = val;
+ break;
+ case REG_R8:
+ rp->r_r8 = val;
+ break;
+ case REG_R9:
+ rp->r_r9 = val;
+ break;
+ case REG_RAX:
+ rp->r_rax = val;
+ break;
+ case REG_RBX:
+ rp->r_rbx = val;
+ break;
+ case REG_RBP:
+ rp->r_rbp = val;
+ break;
+ case REG_R10:
+ rp->r_r10 = val;
+ break;
+ case REG_R11:
+ rp->r_r11 = val;
+ break;
+ case REG_R12:
+ rp->r_r12 = val;
+ break;
+ case REG_R13:
+ rp->r_r13 = val;
+ break;
+ case REG_R14:
+ rp->r_r14 = val;
+ break;
+ case REG_R15:
+ rp->r_r15 = val;
+ break;
+ case REG_RSP:
+ rp->r_rsp = val;
+ break;
+ default:
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return;
+ }
+
+#else /* defined(__amd64) */
+ switch (reg) {
+ case EAX:
+ rp->r_eax = val;
+ break;
+ case ECX:
+ rp->r_ecx = val;
+ break;
+ case EDX:
+ rp->r_edx = val;
+ break;
+ case EBX:
+ rp->r_ebx = val;
+ break;
+ case ESP:
+ rp->r_esp = val;
+ break;
+ case EBP:
+ rp->r_ebp = val;
+ break;
+ case ESI:
+ rp->r_esi = val;
+ break;
+ case EDI:
+ rp->r_edi = val;
+ break;
+ default:
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return;
+ }
+#endif /* defined(__amd64) */
+}
+
static int
dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
{
diff --git a/usr/src/uts/sparc/dtrace/dtrace_isa.c b/usr/src/uts/sparc/dtrace/dtrace_isa.c
index 20d9bc420b..541f733b06 100644
--- a/usr/src/uts/sparc/dtrace/dtrace_isa.c
+++ b/usr/src/uts/sparc/dtrace/dtrace_isa.c
@@ -24,7 +24,7 @@
* Use is subject to license terms.
*/
/*
- * Copyright 2011 Joyent, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
*/
#include <sys/dtrace_impl.h>
@@ -940,6 +940,15 @@ got_fp:
return (value);
}
+/* ARGSUSED */
+int
+dtrace_setreg(struct regs *rp, uint_t reg, ulong_t val)
+{
+ /* Not supported at this time */
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return (0);
+}
+
/*ARGSUSED*/
uint64_t
dtrace_getvmreg(uint_t ndx, volatile uint16_t *flags)