[DTrace-devel] [PATCH v2 3/3] Fix fbt:::return and pid:::return arg1
eugene.loh at oracle.com
eugene.loh at oracle.com
Thu May 5 20:26:26 UTC 2022
From: Eugene Loh <eugene.loh at oracle.com>
Meanwhile, set fbt:::return arg0=-1 to indicate we do not know the
real value.
Also, remove the unused PT_REGS_BPF_*().
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cg.c | 24 +++++++++++-
libdtrace/dt_cg.h | 1 +
libdtrace/dt_prov_fbt.c | 20 +++++++++-
libdtrace/dt_prov_pid.c | 5 ++-
libdtrace/dt_pt_regs.h | 25 ++-----------
test/unittest/fbtprovider/tst.return0.d | 6 +--
test/unittest/fbtprovider/tst.return0.r | 1 +
test/unittest/fbtprovider/tst.return1.d | 50 +++++++++++++++++++++++++
test/unittest/fbtprovider/tst.return1.r | 1 +
test/unittest/pid/tst.ret1.d | 3 +-
test/unittest/pid/tst.ret2.d | 3 +-
11 files changed, 105 insertions(+), 34 deletions(-)
create mode 100644 test/unittest/fbtprovider/tst.return0.r
create mode 100644 test/unittest/fbtprovider/tst.return1.d
create mode 100644 test/unittest/fbtprovider/tst.return1.r
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 3c97a6c9..4729710d 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -279,7 +279,7 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
/*
* for (i = 0; i < PT_REGS_ARGC; i++)
- * dctx->mst->argv[i] = PT_REGS_BPF_ARGi((dt_pt_regs *)rp);
+ * dctx->mst->argv[i] = PT_REGS_ARGi((dt_pt_regs *)rp);
* // lddw %r0, [%rp + PT_REGS_ARGi]
* // stdw [%r7 + DMST_ARG(i)], %r0
*/
@@ -369,6 +369,28 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
}
}
+/*
+ * Copy return value from a dt_pt_regs structure referenced by the 'rp' argument.
+ * to mst->arg[1]. Zero the other args.
+ *
+ * The caller must ensure that %r7 contains the value set by the
+ * dt_cg_tramp_prologue*() functions.
+ */
+void
+dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp)
+{
+ dt_irlist_t *dlp = &pcb->pcb_ir;
+ int i;
+
+ emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(0), 0));
+
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_RET));
+ emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
+
+ for (i = 2; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
+ emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(i), 0));
+}
+
typedef struct {
dt_irlist_t *dlp;
dt_activity_t act;
diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
index 5752151b..bc592fea 100644
--- a/libdtrace/dt_cg.h
+++ b/libdtrace/dt_cg.h
@@ -25,6 +25,7 @@ extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp);
extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp);
+extern void dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp);
extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
dt_activity_t act);
extern void dt_cg_tramp_return(dt_pcb_t *pcb);
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index 62fea51e..ff2fd364 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -167,9 +167,25 @@ static void trampoline(dt_pcb_t *pcb)
* // (%r7 = dctx->mst)
* // (%r8 = dctx->ctx)
*/
-
dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
- dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
+ if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
+ dt_irlist_t *dlp = &pcb->pcb_ir;
+
+ dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
+
+ /*
+ * fbt:::return arg0 should be the function offset for
+ * return instruction. Since we use kretprobes, however,
+ * which do not fire until the function has returned to
+ * its caller, information about the returning instruction
+ * in the callee has been lost.
+ *
+ * Set arg0=-1 to indicate that we do not know the value.
+ */
+ dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_0, -1);
+ emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+ } else
+ dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
dt_cg_tramp_epilogue(pcb);
}
diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
index af894f79..d2b1b0d7 100644
--- a/libdtrace/dt_prov_pid.c
+++ b/libdtrace/dt_prov_pid.c
@@ -211,7 +211,10 @@ static void trampoline(dt_pcb_t *pcb)
*/
dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
- dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
+ if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0)
+ dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
+ else
+ dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
/*
* Retrieve the PID of the process that caused the probe to fire.
diff --git a/libdtrace/dt_pt_regs.h b/libdtrace/dt_pt_regs.h
index 5f851573..057f1fdb 100644
--- a/libdtrace/dt_pt_regs.h
+++ b/libdtrace/dt_pt_regs.h
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -19,7 +19,7 @@ extern "C" {
#if defined(__amd64)
typedef struct pt_regs dt_pt_regs;
-
+# define PT_REGS_RET offsetof(dt_pt_regs, rax)
# define PT_REGS_ARG0 offsetof(dt_pt_regs, rdi)
# define PT_REGS_ARG1 offsetof(dt_pt_regs, rsi)
# define PT_REGS_ARG2 offsetof(dt_pt_regs, rdx)
@@ -30,17 +30,9 @@ typedef struct pt_regs dt_pt_regs;
# define PT_REGS_ARGSTKBASE 1
# define PT_REGS_IP offsetof(dt_pt_regs, rip)
# define PT_REGS_SP offsetof(dt_pt_regs, rsp)
-
-# define PT_REGS_BPF_ARG0(r) ((r)->rdi)
-# define PT_REGS_BPF_ARG1(r) ((r)->rsi)
-# define PT_REGS_BPF_ARG2(r) ((r)->rdx)
-# define PT_REGS_BPF_ARG3(r) ((r)->rcx)
-# define PT_REGS_BPF_ARG4(r) ((r)->r8)
-# define PT_REGS_BPF_ARG5(r) ((r)->r9)
-# define PT_REGS_BPF_IP(r) ((r)->rip)
-# define PT_REGS_BPF_SP(r) ((r)->rsp)
#elif defined(__aarch64__)
typedef struct user_pt_regs dt_pt_regs;
+# define PT_REGS_RET offsetof(dt_pt_regs, regs[0])
# define PT_REGS_ARG0 offsetof(dt_pt_regs, regs[0])
# define PT_REGS_ARG1 offsetof(dt_pt_regs, regs[1])
# define PT_REGS_ARG2 offsetof(dt_pt_regs, regs[2])
@@ -53,17 +45,6 @@ typedef struct user_pt_regs dt_pt_regs;
# define PT_REGS_ARGSTKBASE 0
# define PT_REGS_IP offsetof(dt_pt_regs, pc)
# define PT_REGS_SP offsetof(dt_pt_regs, sp)
-
-# define PT_REGS_BPF_ARG0(r) ((r)->regs[0])
-# define PT_REGS_BPF_ARG1(r) ((r)->regs[1])
-# define PT_REGS_BPF_ARG2(r) ((r)->regs[2])
-# define PT_REGS_BPF_ARG3(r) ((r)->regs[3])
-# define PT_REGS_BPF_ARG4(r) ((r)->regs[4])
-# define PT_REGS_BPF_ARG5(r) ((r)->regs[5])
-# define PT_REGS_BPF_ARG6(r) ((r)->regs[6])
-# define PT_REGS_BPF_ARG7(r) ((r)->regs[7])
-# define PT_REGS_BPF_IP(r) ((r)->pc)
-# define PT_REGS_BPF_SP(r) ((r)->sp)
#else
# error ISA not supported
#endif
diff --git a/test/unittest/fbtprovider/tst.return0.d b/test/unittest/fbtprovider/tst.return0.d
index 3d58e84f..0b7091b3 100644
--- a/test/unittest/fbtprovider/tst.return0.d
+++ b/test/unittest/fbtprovider/tst.return0.d
@@ -1,18 +1,16 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/*
- * ASSERTION: simple fbt provider arg0 and probfunc print test.
+ * ASSERTION: simple fbt provider arg0 and probefunc print test.
*
* SECTION: FBT Provider/Probe arguments
*/
-/* @@runtest-opts: -Z */
-
#pragma D option quiet
#pragma D option statusrate=10ms
diff --git a/test/unittest/fbtprovider/tst.return0.r b/test/unittest/fbtprovider/tst.return0.r
new file mode 100644
index 00000000..53308c30
--- /dev/null
+++ b/test/unittest/fbtprovider/tst.return0.r
@@ -0,0 +1 @@
+do_sys_poll ffffffffffffffff returned 0
diff --git a/test/unittest/fbtprovider/tst.return1.d b/test/unittest/fbtprovider/tst.return1.d
new file mode 100644
index 00000000..751e8865
--- /dev/null
+++ b/test/unittest/fbtprovider/tst.return1.d
@@ -0,0 +1,50 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/* @@trigger: bogus-ioctl */
+/* @@trigger-timing: before */
+/* @@runtest-opts: $_pid */
+
+#pragma D option destructive
+#pragma D option quiet
+#pragma D option zdefs
+
+BEGIN
+{
+ niter = 0;
+ rval = -1;
+}
+
+/* notify the trigger to exit its ioctl() loop */
+syscall::ioctl:entry
+/pid == $1/
+{
+ raise(SIGUSR1);
+}
+
+/* if we enter open(), reset the expected return value */
+syscall::open*:entry
+/pid == $1/
+{
+ reset = 1;
+}
+
+/* check the return value (the first probe resets the expected value) */
+syscall:vmlinux:open*:return,
+fbt:vmlinux:do_sys_open*:return
+/pid == $1/
+{
+ rval = (reset ? arg1 : rval);
+ printf("%s", arg1 == rval ? "" : "ERROR mismatch\n");
+ reset = 0;
+}
+
+syscall::open*:return
+/pid == $1 && ++niter >= 20/
+{
+ exit(0);
+}
diff --git a/test/unittest/fbtprovider/tst.return1.r b/test/unittest/fbtprovider/tst.return1.r
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/unittest/fbtprovider/tst.return1.r
@@ -0,0 +1 @@
+
diff --git a/test/unittest/pid/tst.ret1.d b/test/unittest/pid/tst.ret1.d
index bdf7d274..398e2cc8 100644
--- a/test/unittest/pid/tst.ret1.d
+++ b/test/unittest/pid/tst.ret1.d
@@ -1,10 +1,9 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/* @@runtest-opts: $_pid */
/* @@trigger: pid-tst-ret1 */
/* @@trigger-timing: before */
diff --git a/test/unittest/pid/tst.ret2.d b/test/unittest/pid/tst.ret2.d
index d3d482e3..a542646a 100644
--- a/test/unittest/pid/tst.ret2.d
+++ b/test/unittest/pid/tst.ret2.d
@@ -1,10 +1,9 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/* @@runtest-opts: $_pid */
/* @@trigger: pid-tst-ret2 */
/* @@trigger-timing: before */
--
2.18.4
More information about the DTrace-devel
mailing list