From fd09db08e45c1c6ae2489c65176d88086dcb1a4d Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Tue, 16 May 2017 09:55:41 -0400 Subject: [PATCH] dtrace: support passing offset as arg0 to FBT return probes FBT return probes pass the offset from the function start (in bytes) as arg0. To make that possible, we pass the offset value in the call to fbt_add_probe. For FBT entry probes we pass 0 (which is ignored). This commit also ensures that we emulate the 'ret' instruction on the return path. Orabug: 25949086 Signed-off-by: Kris Van Hees Reviewed-by: Tomas Jedlicka Acked-by: Nick Alcock --- dtrace/fbt_dev.c | 5 ++++- dtrace/fbt_x86_64.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/dtrace/fbt_dev.c b/dtrace/fbt_dev.c index 2d292a0a20e5..9d0ddd948799 100644 --- a/dtrace/fbt_dev.c +++ b/dtrace/fbt_dev.c @@ -43,7 +43,8 @@ int fbt_probetab_size = FBT_PROBETAB_SIZE; int fbt_probetab_mask; static void *fbt_provide_probe(struct module *mp, char *func, int type, int - stype, asm_instr_t *addr, void *pfbt) + stype, asm_instr_t *addr, uintptr_t off, + void *pfbt) { fbt_probe_t *fbp; fbt_probe_t *prev; @@ -57,6 +58,7 @@ static void *fbt_provide_probe(struct module *mp, char *func, int type, int fbp->fbp_module = mp; fbp->fbp_loadcnt = 1; /* FIXME */ fbp->fbp_primary = 1; /* FIXME */ + fbp->fbp_roffset = off; fbp->fbp_patchpoint = addr; fbt_provide_probe_arch(fbp, type, stype); fbp->fbp_hashnext = fbt_probetab[FBT_ADDR2NDX(addr)]; @@ -83,6 +85,7 @@ static void *fbt_provide_probe(struct module *mp, char *func, int type, int fbp->fbp_module = mp; fbp->fbp_loadcnt = 1; /* FIXME */ fbp->fbp_primary = 1; /* FIXME */ + fbp->fbp_roffset = off; fbp->fbp_patchpoint = addr; fbt_provide_probe_arch(fbp, type, stype); fbp->fbp_hashnext = fbt_probetab[FBT_ADDR2NDX(addr)]; diff --git a/dtrace/fbt_x86_64.c b/dtrace/fbt_x86_64.c index 9a873c7cec2b..45eb7eb5ee78 100644 --- a/dtrace/fbt_x86_64.c +++ b/dtrace/fbt_x86_64.c @@ -41,9 +41,13 @@ static uint8_t fbt_invop(struct pt_regs *regs) for (; fbp != NULL; fbp = fbp->fbp_hashnext) { if ((uintptr_t)fbp->fbp_patchpoint == regs->ip) { this_cpu_core->cpu_dtrace_regs = regs; - - dtrace_probe(fbp->fbp_id, regs->di, regs->si, - regs->dx, regs->cx, regs->r8); + if (fbp->fbp_roffset == 0) { + dtrace_probe(fbp->fbp_id, regs->di, regs->si, + regs->dx, regs->cx, regs->r8); + } else { + dtrace_probe(fbp->fbp_id, fbp->fbp_roffset, + regs->ax, 0, 0, 0); + } this_cpu_core->cpu_dtrace_regs = NULL; @@ -58,7 +62,7 @@ void fbt_provide_probe_arch(fbt_probe_t *fbp, int type, int stype) { fbp->fbp_patchval = FBT_PATCHVAL; fbp->fbp_savedval = *fbp->fbp_patchpoint; - fbp->fbp_rval = type == FBT_ENTRY ? DTRACE_INVOP_MOV_RSP_RBP + fbp->fbp_rval = type == FBT_ENTRY ? DTRACE_INVOP_PUSH_BP : DTRACE_INVOP_RET; } -- 2.50.1