[DTrace-devel] [PATCH 4/5] Work in Progress: Add a different version of strchr()

eugene.loh at oracle.com eugene.loh at oracle.com
Wed Aug 25 19:21:37 PDT 2021


From: Eugene Loh <eugene.loh at oracle.com>

Just park this version here for now.  It loops over individual
chars and bypasses the extra copies of the earlier version.  So
it is arguably cleaner.  While it generates about "15x" more
branching for the BPF verifier than the earlier version did,
this version still seems quite usable.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 bpf/strchr2.S | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 bpf/strchr2.S

diff --git a/bpf/strchr2.S b/bpf/strchr2.S
new file mode 100644
index 00000000..805f4993
--- /dev/null
+++ b/bpf/strchr2.S
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#define BPF_FUNC_probe_read	4
+
+/*
+ * char *dt_strchr(char *s, uint64_t c, char *t) {
+ *
+ *     c <<= 56;
+ *
+ *     [%fp-8]=s
+ *     [%fp-16]=c
+ *     [%fp-24]=t
+ *
+ *     r6 = dt_vint2int(s);
+ *     r7 = dt_vint_size(r6);
+ *
+ *     r8 = 0;
+ * Lloop:
+ *     r3 = s[r7 + r8];
+ *     r3 <<= 56;
+ *     if (r3 == c) goto Lfound;
+ *     r8++;
+ *     if (r8 < r6) goto Lloop;
+ *
+ *     return NULL;
+ *
+ * Lfound:
+ *     r6 -= r8;
+ *     r9 = dt_int2vint(r6, t);
+ *     r7 += r8;
+ *     bpf_probe_read(t + r9, r6, s + r7);
+ *
+ *     r6 += r9;
+ *     t[r6] = '\0';
+ *
+ *     return t;
+ * }
+ */
+	.text
+	.align	4
+	.global	dt_strchr
+dt_strchr :
+	lsh	%r2, 56			/* c <<= 56 */
+
+	stxdw	[%fp+-8], %r1		/* Spill s */
+	stxdw	[%fp+-16], %r2		/* Spill c */
+	stxdw	[%fp+-24], %r3		/* Spill t */
+
+	call	dt_vint2int		/* r6 = dt_vint2int(s) */
+
+	and	%r0, 0xfffffff		/* bound r6 */
+	lddw	%r1, STRSZ
+	jle	%r0, %r1, 1
+	mov	%r0, %r1
+	mov	%r6, %r0
+
+	mov	%r1, %r6
+	call	dt_vint_size		/* r7 = dt_vint_size(r6) */
+	mov	%r7, %r0
+
+	mov	%r8, 0			/* r8 = 0 */
+
+	ldxdw	%r5, [%fp+-16]
+.Lloop:
+	mov	%r4, %r7
+	add	%r4, %r8
+	jge	%r4, %r6, .Lnone
+	ldxdw	%r3, [%fp+-8]
+	add	%r3, %r4
+	ldxb	%r3, [%r3+0]		/* r3 = s[r7 + r8] */
+	lsh	%r3, 56			/* r3 <<= 56 */
+	jeq	%r3, %r5, .Lfound	/* if (r3 == c) goto Lfound */
+	add	%r8, 1			/* r8++ */
+	ja	.Lloop			/* if (r8 < r6) goto Lloop */
+
+.Lnone:
+	mov	%r0, 0			/* return NULL */
+	exit
+
+.Lfound:
+	sub	%r6, %r8		/* r6 -= r8 */
+	jge	%r6, 0, 1
+	mov	%r6, 0
+	and	%r6, 0xffff
+	lddw	%r1, STRSZ
+	jle	%r6, %r1, 1
+	mov	%r6, %r1
+
+	mov	%r1, %r6
+	ldxdw	%r2, [%fp+-24]
+	call	dt_int2vint		/* r9 = dt_int2vint(r6, t) */
+	mov	%r9, %r0
+
+	add	%r7, %r8		/* r7 += r8 */
+
+	ldxdw	%r1, [%fp+-24]
+	add	%r1, %r9
+	mov	%r2, %r6
+	ldxdw	%r3, [%fp+-8]
+	add	%r3, %r7
+	call	BPF_FUNC_probe_read	/* bpf_probe_read(t + r9, r6, s + r7) */
+
+	add	%r6, %r9		/* r6 += r9 */
+	ldxdw	%r1, [%fp+-24]
+	add	%r1, %r6		/* t[r6] = '\0' */
+	mov	%r2, 0
+	stxb	[%r1+0], %r2
+
+	ldxdw	%r0, [%fp+-24]		/* return t */
+	exit
-- 
2.18.4




More information about the DTrace-devel mailing list