From 6c2806594b351ec39cca31bf386bdee79571fa36 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 17 Apr 2016 23:08:47 +0000 Subject: [PATCH] Make the second argument of dtrace_invop() a trapframe pointer. Currently this argument is a pointer into the stack which is used by FBT to fetch the first five probe arguments. On all non-x86 architectures it's simply the trapframe address, so this change has no functional impact. On amd64 it's a pointer into the trapframe such that stack[1 .. 5] gives the first five argument registers, which are deliberately grouped together in the amd64 trapframe definition. A trapframe argument simplifies the invop handlers on !x86 and makes the x86 FBT invop handler easier to understand. Moreover, it allows for invop handlers that may want to modify the register set of the interrupted thread. --- .../opensolaris/uts/common/sys/dtrace.h | 7 ++- sys/cddl/dev/dtrace/aarch64/dtrace_subr.c | 14 +++--- sys/cddl/dev/dtrace/amd64/dtrace_asm.S | 5 +- sys/cddl/dev/dtrace/amd64/dtrace_isa.c | 5 +- sys/cddl/dev/dtrace/amd64/dtrace_subr.c | 12 ++--- sys/cddl/dev/dtrace/arm/dtrace_subr.c | 14 +++--- sys/cddl/dev/dtrace/i386/dtrace_asm.S | 2 +- sys/cddl/dev/dtrace/i386/dtrace_isa.c | 21 +++++--- sys/cddl/dev/dtrace/i386/dtrace_subr.c | 12 ++--- sys/cddl/dev/dtrace/mips/dtrace_subr.c | 4 +- sys/cddl/dev/dtrace/powerpc/dtrace_subr.c | 17 +++---- sys/cddl/dev/fbt/aarch64/fbt_isa.c | 4 +- sys/cddl/dev/fbt/arm/fbt_isa.c | 3 +- sys/cddl/dev/fbt/fbt.h | 3 +- sys/cddl/dev/fbt/powerpc/fbt_isa.c | 3 +- sys/cddl/dev/fbt/x86/fbt_isa.c | 49 ++++++++++++++----- 16 files changed, 100 insertions(+), 75 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index 72242420ba9..a8b537f6999 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -2398,8 +2398,9 @@ extern int dtrace_instr_size(uchar_t *instr); extern int dtrace_instr_size_isa(uchar_t *, model_t, int *); extern void dtrace_invop_callsite(void); #endif -extern void dtrace_invop_add(int (*)(uintptr_t, uintptr_t *, uintptr_t)); -extern void dtrace_invop_remove(int (*)(uintptr_t, uintptr_t *, uintptr_t)); +extern void dtrace_invop_add(int (*)(uintptr_t, struct trapframe *, uintptr_t)); +extern void dtrace_invop_remove(int (*)(uintptr_t, struct trapframe *, + uintptr_t)); #ifdef __sparc extern int dtrace_blksuword32(uintptr_t, uint32_t *, int); @@ -2427,7 +2428,9 @@ extern void dtrace_helpers_destroy(proc_t *); #if defined(__i386) || defined(__amd64) #define DTRACE_INVOP_PUSHL_EBP 1 +#define DTRACE_INVOP_PUSHQ_RBP DTRACE_INVOP_PUSHL_EBP #define DTRACE_INVOP_POPL_EBP 2 +#define DTRACE_INVOP_POPQ_RBP DTRACE_INVOP_POPL_EBP #define DTRACE_INVOP_LEAVE 3 #define DTRACE_INVOP_NOP 4 #define DTRACE_INVOP_RET 5 diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c index 78b56376ec2..60afe1cdbbc 100644 --- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c @@ -49,25 +49,25 @@ extern dtrace_id_t dtrace_probeid_error; extern int (*dtrace_invop_jump_addr)(struct trapframe *); extern void dtrace_getnanotime(struct timespec *tsp); -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); void dtrace_invop_init(void); void dtrace_invop_uninit(void); typedef struct dtrace_invop_hdlr { - int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); struct dtrace_invop_hdlr *dtih_next; } dtrace_invop_hdlr_t; dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) { dtrace_invop_hdlr_t *hdlr; int rval; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0) + if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) return (rval); return (0); @@ -75,7 +75,7 @@ dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) void -dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr; @@ -86,7 +86,7 @@ dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) } void -dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr, *prev; @@ -240,7 +240,7 @@ dtrace_invop_start(struct trapframe *frame) int tmp; int i; - invop = dtrace_invop(frame->tf_elr, (uintptr_t *)frame, frame->tf_elr); + invop = dtrace_invop(frame->tf_elr, frame, frame->tf_elr); tmp = (invop & LDP_STP_MASK); if (tmp == STP_64 || tmp == LDP_64) { diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S index eb5856d1b51..09eea5606e4 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S +++ b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S @@ -69,13 +69,10 @@ */ movq TF_RIP(%rsp), %rdi decq %rdi - movq TF_RSP(%rsp), %rsi - movq TF_RAX(%rsp), %rdx - pushq (%rsi) movq %rsp, %rsi + movq TF_RAX(%rsp), %rdx call dtrace_invop ALTENTRY(dtrace_invop_callsite) - addq $8, %rsp cmpl $DTRACE_INVOP_PUSHL_EBP, %eax je bp_push cmpl $DTRACE_INVOP_LEAVE, %eax diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c index f6d408e3403..603921a35d8 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -382,11 +382,10 @@ dtrace_getarg(int arg, int aframes) * we'll pull the true stack pointer out of the saved * registers and decrement our argument by the number * of arguments passed in registers; if the argument - * we're seeking is passed in regsiters, we can just + * we're seeking is passed in registers, we can just * load it directly. */ - struct trapframe *tf = (struct trapframe *) - ((uintptr_t)&fp[1] + sizeof(uintptr_t)); + struct trapframe *tf = (struct trapframe *)&fp[1]; if (arg <= inreg) { switch (arg) { diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c index 2a26b658996..1d81d42c98b 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c @@ -46,30 +46,30 @@ extern void dtrace_getnanotime(struct timespec *tsp); -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); typedef struct dtrace_invop_hdlr { - int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); struct dtrace_invop_hdlr *dtih_next; } dtrace_invop_hdlr_t; dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) { dtrace_invop_hdlr_t *hdlr; int rval; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0) + if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) return (rval); return (0); } void -dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr; @@ -80,7 +80,7 @@ dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) } void -dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL; diff --git a/sys/cddl/dev/dtrace/arm/dtrace_subr.c b/sys/cddl/dev/dtrace/arm/dtrace_subr.c index 44dde295265..4ff4e71183b 100644 --- a/sys/cddl/dev/dtrace/arm/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/arm/dtrace_subr.c @@ -55,25 +55,25 @@ extern dtrace_id_t dtrace_probeid_error; extern int (*dtrace_invop_jump_addr)(struct trapframe *); extern void dtrace_getnanotime(struct timespec *tsp); -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); void dtrace_invop_init(void); void dtrace_invop_uninit(void); typedef struct dtrace_invop_hdlr { - int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); struct dtrace_invop_hdlr *dtih_next; } dtrace_invop_hdlr_t; dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) { dtrace_invop_hdlr_t *hdlr; int rval; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0) + if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) return (rval); return (0); @@ -81,7 +81,7 @@ dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) void -dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr; @@ -92,7 +92,7 @@ dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) } void -dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL; @@ -237,7 +237,7 @@ dtrace_invop_start(struct trapframe *frame) register_t *r0, *sp; int data, invop, reg, update_sp; - invop = dtrace_invop(frame->tf_pc, (uintptr_t *)frame, frame->tf_pc); + invop = dtrace_invop(frame->tf_pc, frame, frame->tf_pc); switch (invop & DTRACE_INVOP_MASK) { case DTRACE_INVOP_PUSHM: sp = (register_t *)frame->tf_svc_sp; diff --git a/sys/cddl/dev/dtrace/i386/dtrace_asm.S b/sys/cddl/dev/dtrace/i386/dtrace_asm.S index 425e99c3898..5dac5ef4b8c 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_asm.S +++ b/sys/cddl/dev/dtrace/i386/dtrace_asm.S @@ -38,7 +38,7 @@ pushl %eax /* push %eax -- may be return value */ pushl %esp /* push stack pointer */ - addl $48, (%esp) /* adjust to incoming args */ + subl $8, (%esp) /* skip first arg and segment regs */ pushl 40(%esp) /* push calling EIP */ /* diff --git a/sys/cddl/dev/dtrace/i386/dtrace_isa.c b/sys/cddl/dev/dtrace/i386/dtrace_isa.c index 63a7c085d26..6da1b5088f5 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_isa.c @@ -423,9 +423,9 @@ zero: uint64_t dtrace_getarg(int arg, int aframes) { - uintptr_t val; + struct trapframe *frame; struct i386_frame *fp = (struct i386_frame *)dtrace_getfp(); - uintptr_t *stack; + uintptr_t *stack, val; int i; for (i = 1; i <= aframes; i++) { @@ -435,13 +435,18 @@ dtrace_getarg(int arg, int aframes) (long)dtrace_invop_callsite) { /* * If we pass through the invalid op handler, we will - * use the pointer that it passed to the stack as the - * second argument to dtrace_invop() as the pointer to - * the stack. When using this stack, we must step - * beyond the EIP/RIP that was pushed when the trap was - * taken -- hence the "+ 1" below. + * use the trap frame pointer that it pushed on the + * stack as the second argument to dtrace_invop() as + * the pointer to the stack. When using this stack, we + * must skip the third argument to dtrace_invop(), + * which is included in the i386_frame. */ - stack = ((uintptr_t **)&fp[1])[0] + 1; + frame = (struct trapframe *)(((uintptr_t **)&fp[1])[0]); + /* + * Skip the three hardware-saved registers and the + * return address. + */ + stack = (uintptr_t *)frame->tf_isp + 4; goto load; } diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c index daca7dda58f..a2263ecccfa 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c @@ -49,30 +49,30 @@ extern uintptr_t kernelbase; extern void dtrace_getnanotime(struct timespec *tsp); -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); typedef struct dtrace_invop_hdlr { - int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); struct dtrace_invop_hdlr *dtih_next; } dtrace_invop_hdlr_t; dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) { dtrace_invop_hdlr_t *hdlr; int rval; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0) + if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) return (rval); return (0); } void -dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr; @@ -83,7 +83,7 @@ dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) } void -dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL; diff --git a/sys/cddl/dev/dtrace/mips/dtrace_subr.c b/sys/cddl/dev/dtrace/mips/dtrace_subr.c index a2aa8c7e332..97022746c44 100644 --- a/sys/cddl/dev/dtrace/mips/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/mips/dtrace_subr.c @@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$"); extern dtrace_id_t dtrace_probeid_error; -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); typedef struct dtrace_invop_hdlr { int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); @@ -58,7 +58,7 @@ typedef struct dtrace_invop_hdlr { dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *stack, uintptr_t eax) { dtrace_invop_hdlr_t *hdlr; int rval; diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c index 33b9e7120cb..35461474605 100644 --- a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c @@ -51,32 +51,32 @@ extern int (*dtrace_invop_jump_addr)(struct trapframe *); extern void dtrace_getnanotime(struct timespec *tsp); -int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); void dtrace_invop_init(void); void dtrace_invop_uninit(void); typedef struct dtrace_invop_hdlr { - int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t); + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); struct dtrace_invop_hdlr *dtih_next; } dtrace_invop_hdlr_t; dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t arg0) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t arg0) { dtrace_invop_hdlr_t *hdlr; int rval; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, stack, arg0)) != 0) + if ((rval = hdlr->dtih_func(addr, frame, arg0)) != 0) return (rval); return (0); } void -dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr; @@ -87,7 +87,7 @@ dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) } void -dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t)) +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) { dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL; @@ -326,7 +326,8 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, static int dtrace_invop_start(struct trapframe *frame) { - switch (dtrace_invop(frame->srr0, (uintptr_t *)frame, frame->fixreg[3])) { + + switch (dtrace_invop(frame->srr0, frame, frame->fixreg[3])) { case DTRACE_INVOP_JUMP: break; case DTRACE_INVOP_BCTR: @@ -341,9 +342,7 @@ dtrace_invop_start(struct trapframe *frame) break; default: return (-1); - break; } - return (0); } diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c index 627fdf9c30c..1231140a425 100644 --- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c +++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c @@ -46,13 +46,11 @@ #define FBT_RETURN "return" int -fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) +fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) { - struct trapframe *frame; solaris_cpu_t *cpu; fbt_probe_t *fbt; - frame = (struct trapframe *)stack; cpu = &solaris_cpu[curcpu]; fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c index 2e0e5a5eae1..592e59802bb 100644 --- a/sys/cddl/dev/fbt/arm/fbt_isa.c +++ b/sys/cddl/dev/fbt/arm/fbt_isa.c @@ -49,9 +49,8 @@ #define FBT_RETURN "return" int -fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) +fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) { - struct trapframe *frame = (struct trapframe *)stack; solaris_cpu_t *cpu = &solaris_cpu[curcpu]; fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; register_t fifthparam; diff --git a/sys/cddl/dev/fbt/fbt.h b/sys/cddl/dev/fbt/fbt.h index ea245cb0b8e..f34025917b8 100644 --- a/sys/cddl/dev/fbt/fbt.h +++ b/sys/cddl/dev/fbt/fbt.h @@ -51,8 +51,9 @@ typedef struct fbt_probe { struct linker_file; struct linker_symval; +struct trapframe; -int fbt_invop(uintptr_t, uintptr_t *, uintptr_t); +int fbt_invop(uintptr_t, struct trapframe *, uintptr_t); void fbt_patch_tracepoint(fbt_probe_t *, fbt_patchval_t); int fbt_provide_module_function(struct linker_file *, int, struct linker_symval *, void *); diff --git a/sys/cddl/dev/fbt/powerpc/fbt_isa.c b/sys/cddl/dev/fbt/powerpc/fbt_isa.c index d55d553d9cd..0568e55046d 100644 --- a/sys/cddl/dev/fbt/powerpc/fbt_isa.c +++ b/sys/cddl/dev/fbt/powerpc/fbt_isa.c @@ -51,9 +51,8 @@ #define FBT_AFRAMES 7 int -fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) +fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) { - struct trapframe *frame = (struct trapframe *)stack; solaris_cpu_t *cpu = &solaris_cpu[curcpu]; fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; uintptr_t tmp; diff --git a/sys/cddl/dev/fbt/x86/fbt_isa.c b/sys/cddl/dev/fbt/x86/fbt_isa.c index 4514b34d512..6639806d11a 100644 --- a/sys/cddl/dev/fbt/x86/fbt_isa.c +++ b/sys/cddl/dev/fbt/x86/fbt_isa.c @@ -58,16 +58,40 @@ #define FBT_RETURN "return" int -fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) +fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) { - solaris_cpu_t *cpu = &solaris_cpu[curcpu]; - uintptr_t stack0, stack1, stack2, stack3, stack4; - fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; + solaris_cpu_t *cpu; + uintptr_t *stack; + uintptr_t arg0, arg1, arg2, arg3, arg4; + fbt_probe_t *fbt; +#ifdef __amd64__ + stack = (uintptr_t *)frame->tf_rsp; +#else + /* Skip hardware-saved registers. */ + stack = (uintptr_t *)frame->tf_isp + 3; +#endif + + cpu = &solaris_cpu[curcpu]; + fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { if ((uintptr_t)fbt->fbtp_patchpoint == addr) { if (fbt->fbtp_roffset == 0) { +#ifdef __amd64__ + /* fbt->fbtp_rval == DTRACE_INVOP_PUSHQ_RBP */ + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); + cpu->cpu_dtrace_caller = stack[0]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | + CPU_DTRACE_BADADDR); + + arg0 = frame->tf_rdi; + arg1 = frame->tf_rsi; + arg2 = frame->tf_rdx; + arg3 = frame->tf_rcx; + arg4 = frame->tf_r8; +#else int i = 0; + /* * When accessing the arguments on the stack, * we must protect against accessing beyond @@ -77,16 +101,17 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) */ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); cpu->cpu_dtrace_caller = stack[i++]; - stack0 = stack[i++]; - stack1 = stack[i++]; - stack2 = stack[i++]; - stack3 = stack[i++]; - stack4 = stack[i++]; + arg0 = stack[i++]; + arg1 = stack[i++]; + arg2 = stack[i++]; + arg3 = stack[i++]; + arg4 = stack[i++]; DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR); +#endif - dtrace_probe(fbt->fbtp_id, stack0, stack1, - stack2, stack3, stack4); + dtrace_probe(fbt->fbtp_id, arg0, arg1, + arg2, arg3, arg4); cpu->cpu_dtrace_caller = 0; } else { @@ -94,7 +119,7 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) /* * On amd64, we instrument the ret, not the * leave. We therefore need to set the caller - * to assure that the top frame of a stack() + * to ensure that the top frame of a stack() * action is correct. */ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);