[DTrace-devel] [PATCH v2] Add support for getmajor() and getminor() subroutines
eugene.loh at oracle.com
eugene.loh at oracle.com
Thu Feb 17 02:36:51 UTC 2022
From: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cg.c | 30 ++++++++++++++++++++++++++++--
test/unittest/funcs/tst.getmajor.d | 19 +++++++++++++++++++
test/unittest/funcs/tst.getmajor.r | 1 +
test/unittest/funcs/tst.getminor.d | 19 +++++++++++++++++++
test/unittest/funcs/tst.getminor.r | 1 +
5 files changed, 68 insertions(+), 2 deletions(-)
create mode 100644 test/unittest/funcs/tst.getmajor.d
create mode 100644 test/unittest/funcs/tst.getmajor.r
create mode 100644 test/unittest/funcs/tst.getminor.d
create mode 100644 test/unittest/funcs/tst.getminor.r
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index b6b39617..2652b5fc 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3374,6 +3374,32 @@ dt_cg_subr_dirname(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_subr_path_helper(dnp, dlp, drp, "dt_dirname");
}
+/*
+ * For getmajor and getminor, use MAJOR(dev) and MINOR(dev)
+ * as defined in kernel header include/linux/kdev_t.h, not
+ * as defined in user header /usr/include/linux/kdev_t.h.
+ */
+static void
+dt_cg_subr_getmajor(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dt_node_t *arg = dnp->dn_args;
+
+ dt_cg_node(arg, dlp, drp);
+ dnp->dn_reg = arg->dn_reg;
+ emit(dlp, BPF_ALU64_IMM(BPF_LSH, dnp->dn_reg, 32));
+ emit(dlp, BPF_ALU64_IMM(BPF_RSH, dnp->dn_reg, 32 + 20));
+}
+
+static void
+dt_cg_subr_getminor(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dt_node_t *arg = dnp->dn_args;
+
+ dt_cg_node(arg, dlp, drp);
+ dnp->dn_reg = arg->dn_reg;
+ emit(dlp, BPF_ALU64_IMM(BPF_AND, dnp->dn_reg, 0xfffff));
+}
+
/*
* Get and return a new speculation ID. These are unallocated entries in the
* specs map, obtained by calling dt_speculation(). Return zero if none is
@@ -4120,8 +4146,8 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
[DIF_SUBR_COPYINTO] = NULL,
[DIF_SUBR_MSGDSIZE] = NULL,
[DIF_SUBR_MSGSIZE] = NULL,
- [DIF_SUBR_GETMAJOR] = NULL,
- [DIF_SUBR_GETMINOR] = NULL,
+ [DIF_SUBR_GETMAJOR] = &dt_cg_subr_getmajor,
+ [DIF_SUBR_GETMINOR] = &dt_cg_subr_getminor,
[DIF_SUBR_DDI_PATHNAME] = NULL,
[DIF_SUBR_STRJOIN] = dt_cg_subr_strjoin,
[DIF_SUBR_LLTOSTR] = &dt_cg_subr_lltostr,
diff --git a/test/unittest/funcs/tst.getmajor.d b/test/unittest/funcs/tst.getmajor.d
new file mode 100644
index 00000000..de0e4800
--- /dev/null
+++ b/test/unittest/funcs/tst.getmajor.d
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%x", getmajor(0xabcdef0123456789ll));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/funcs/tst.getmajor.r b/test/unittest/funcs/tst.getmajor.r
new file mode 100644
index 00000000..7b5813c6
--- /dev/null
+++ b/test/unittest/funcs/tst.getmajor.r
@@ -0,0 +1 @@
+234
diff --git a/test/unittest/funcs/tst.getminor.d b/test/unittest/funcs/tst.getminor.d
new file mode 100644
index 00000000..d1619234
--- /dev/null
+++ b/test/unittest/funcs/tst.getminor.d
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+ printf("%x", getminor(0xabcdef0123456789ll));
+ exit(0);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/funcs/tst.getminor.r b/test/unittest/funcs/tst.getminor.r
new file mode 100644
index 00000000..e2f2476c
--- /dev/null
+++ b/test/unittest/funcs/tst.getminor.r
@@ -0,0 +1 @@
+56789
--
2.18.4
More information about the DTrace-devel
mailing list