[DTrace-devel] [PATCH] Add disassembler annotations for string constants

Kris Van Hees kris.van.hees at oracle.com
Fri Feb 25 04:49:23 UTC 2022


Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_dis.c                       | 51 ++++++++++++++++--------
 test/unittest/disasm/tst.ann-strconst.r  |  1 +
 test/unittest/disasm/tst.ann-strconst.sh | 26 ++++++++++++
 3 files changed, 61 insertions(+), 17 deletions(-)
 create mode 100644 test/unittest/disasm/tst.ann-strconst.r
 create mode 100755 test/unittest/disasm/tst.ann-strconst.sh

diff --git a/libdtrace/dt_dis.c b/libdtrace/dt_dis.c
index efdaf012..f92cfdcf 100644
--- a/libdtrace/dt_dis.c
+++ b/libdtrace/dt_dis.c
@@ -82,9 +82,12 @@ dt_dis_varname_off(const dtrace_difo_t *dp, uint_t off, uint_t scope, uint_t add
 }
 
 /*
- * Check if we are loading either the gvar or lvar BPF map.  If so,
- * we want to report the name of the variable it is looking up.
- * The sequence of instructions we are looking for is:
+ * Check if we are loading from the gvar, lvar, or strtab BPF map.
+ *
+ * If we are loading a gvar or lvar, we want to report the variable name.
+ * If we are loading a string constant, we want to report its value.
+ *
+ * For variables, the sequence of instructions we are looking for is:
  *         insn   code  dst  src    offset        imm
  *          -2:    ld   dst  %fp  DT_STK_DCTX  00000000
  *          -1:    ld   dst  dst  DCTX_*VARS   00000000
@@ -96,15 +99,22 @@ dt_dis_varname_off(const dtrace_difo_t *dp, uint_t off, uint_t scope, uint_t add
  *   - load by value
  *   - store by value
  *   - access by reference
+ *
+ * For string constants, the sequence of instructions we are looking for is:
+ *         insn   code  dst  src    offset        imm
+ *          -2:    ld   dst  %fp  DT_STK_DCTX  00000000
+ *          -1:    ld   dst  dst  DCTX_STRTAB  00000000
+ *           0:    add  dst    0     0         var_offset
+ * where instruction 0 is the current instruction.
  */
 static void
-dt_dis_varname(const dtrace_difo_t *dp, const struct bpf_insn *in, uint_t addr,
+dt_dis_refname(const dtrace_difo_t *dp, const struct bpf_insn *in, uint_t addr,
 	       int n, FILE *fp)
 {
 	__u8		ldcode = BPF_LDX | BPF_MEM | BPF_DW;
 	__u8		addcode = BPF_ALU64 | BPF_ADD | BPF_K;
-	int		dst, scope, var_offset = -1;
-	const char	*vname;
+	int		dst, scope = -1, var_offset = -1;
+	const char	*name;
 
 	/* make sure in[-2] and in[-1] exist */
 	if (addr < 2)
@@ -117,7 +127,7 @@ dt_dis_varname(const dtrace_difo_t *dp, const struct bpf_insn *in, uint_t addr,
 		scope = DIFV_SCOPE_GLOBAL;
 	else if (in[-1].off == DCTX_LVARS)
 		scope = DIFV_SCOPE_LOCAL;
-	else
+	else if (in[-1].off != DCTX_STRTAB)
 		goto out;
 
 	/* check preceding instructions */
@@ -134,8 +144,16 @@ dt_dis_varname(const dtrace_difo_t *dp, const struct bpf_insn *in, uint_t addr,
 	/* check the current instruction and read var_offset */
 	if (in->dst_reg != dst)
 		goto out;
-	if (BPF_CLASS(in->code) == BPF_LDX && BPF_MODE(in->code) == BPF_MEM &&
-	    in->src_reg == dst && in->imm == 0)
+	if (in[-1].off == DCTX_STRTAB &&
+	    in->code == addcode && in->src_reg == 0 && in->off == 0) {
+		name = dt_difo_getstr(dp, in->imm);
+		if (name != NULL)
+			fprintf(fp, "%*s! \"%s\"", DT_DIS_PAD(n), "", name);
+
+		goto out;
+	} else if (BPF_CLASS(in->code) == BPF_LDX &&
+		   BPF_MODE(in->code) == BPF_MEM &&
+		   in->src_reg == dst && in->imm == 0)
 		var_offset = in->off;
 	else if (BPF_CLASS(in->code) == BPF_STX &&
 		 BPF_MODE(in->code) == BPF_MEM &&
@@ -147,11 +165,10 @@ dt_dis_varname(const dtrace_difo_t *dp, const struct bpf_insn *in, uint_t addr,
 		goto out;
 
 	/* print name */
-	vname = dt_dis_varname_off(dp, var_offset, scope, addr);
-	if (vname == NULL)
-		goto out;
-	fprintf(fp, "%*s! %s%s", DT_DIS_PAD(n), "",
-		scope == DIFV_SCOPE_LOCAL ? "this->" : "", vname);
+	name = dt_dis_varname_off(dp, var_offset, scope, addr);
+	if (name != NULL)
+		fprintf(fp, "%*s! %s%s", DT_DIS_PAD(n), "",
+			scope == DIFV_SCOPE_LOCAL ? "this->" : "", name);
 
 out:
 	fprintf(fp, "\n");
@@ -192,7 +209,7 @@ dt_dis_op2imm(const dtrace_difo_t *dp, const char *name, uint_t addr,
 	int		n;
 
 	n = fprintf(fp, "%-4s %s, %d", name, reg(in->dst_reg), in->imm);
-	dt_dis_varname(dp, in, addr, n, fp);
+	dt_dis_refname(dp, in, addr, n, fp);
 
 	return 0;
 }
@@ -233,7 +250,7 @@ dt_dis_load(const dtrace_difo_t *dp, const char *name, uint_t addr,
 	n = fprintf(fp, "%-4s %s, [%s%+d]", name, reg(in->dst_reg),
 		    reg(in->src_reg), in->off);
 
-	dt_dis_varname(dp, in, addr, n, fp);
+	dt_dis_refname(dp, in, addr, n, fp);
 
 	return 0;
 }
@@ -269,7 +286,7 @@ dt_dis_store(const dtrace_difo_t *dp, const char *name, uint_t addr,
 	n = fprintf(fp, "%-4s [%s%+d], %s", name, reg(in->dst_reg), in->off,
 		    reg(in->src_reg));
 
-	dt_dis_varname(dp, in, addr, n, fp);
+	dt_dis_refname(dp, in, addr, n, fp);
 
 	return 0;
 }
diff --git a/test/unittest/disasm/tst.ann-strconst.r b/test/unittest/disasm/tst.ann-strconst.r
new file mode 100644
index 00000000..49273e33
--- /dev/null
+++ b/test/unittest/disasm/tst.ann-strconst.r
@@ -0,0 +1 @@
+07 X 0 0000 XXXXXXXX    add  %rX, D ! "strconst"
diff --git a/test/unittest/disasm/tst.ann-strconst.sh b/test/unittest/disasm/tst.ann-strconst.sh
new file mode 100755
index 00000000..28b54948
--- /dev/null
+++ b/test/unittest/disasm/tst.ann-strconst.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+# 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.
+#
+
+dtrace=$1
+
+$dtrace $dt_flags -Sen '
+BEGIN
+{
+	var = "strconst";
+	exit(0);
+}
+' 2>&1 | \
+	awk '/ ! "strconst"/ {
+		sub(/^[^:]+: /, "");
+		sub(/^07 [0-9a-f] /, "07 X ");
+		sub(/[0-9a-f]{8}    add/, "XXXXXXXX    add");
+		sub(/%r[0-9], [0-9]+ +/, "%rX, D ");
+		print;
+	     }'
+
+exit $?
-- 
2.34.1




More information about the DTrace-devel mailing list