[DTrace-devel] [PATCH 3/3] String args to dt_strcmp() need to be copied if not DPTR
Kris Van Hees
kris.van.hees at oracle.com
Thu Oct 6 16:21:53 UTC 2022
The dt_strcmp() implementation makes use of indirect load instructions
to retrieve characters from either string argument. That only works for
DTrace-managed storage pointers. So, any argument that is not marked
DT_NF_DPTR must be copied into a tstring before the indirect loads are
done.
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
bpf/strcmp.S | 48 ++++++++++++++++++++++++++++++++++++-----------
libdtrace/dt_cg.c | 11 +++++++++++
2 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/bpf/strcmp.S b/bpf/strcmp.S
index 75177469..bdfbb169 100644
--- a/bpf/strcmp.S
+++ b/bpf/strcmp.S
@@ -58,7 +58,7 @@ dt_strcmp_not :
.size dt_strcmp_not, .-dt_strcmp_not
/*
- * int dt_strcmp(char *s, char *t, char *tmp1, char *tmp2) {
+ * int dt_strcmp(char *s, char *t, char *tmp1, char *tmp2, uint64_t flags) {
*
* [%fp-8]=s
* [%fp-16]=t
@@ -86,6 +86,8 @@ dt_strcmp_not :
* // based on this location, judge if the strings are >, <, or ==
* if (r0 > r6) goto Lsame;
* if (r0 > r7) goto Lsame;
+ * if (flags & 1) { bpf_probe_read_str(tmp1, STRSZ, s); s = tmp1; }
+ * if (flags & 2) { bpf_probe_read_str(tmp2, STRSZ, t); t = tmp2; }
* if (s[r0] > t[r0]) return +1;
* if (s[r0] < t[r0]) return +1;
*
@@ -105,6 +107,7 @@ dt_strcmp :
stxdw [%fp+-16], %r2 /* Spill t */
stxdw [%fp+-24], %r3 /* Spill tmp1 */
stxdw [%fp+-32], %r4 /* Spill tmp2 */
+ mov %r9, %r5 /* flags */
lddw %r8, STRSZ /* r8 = STRSZ */
@@ -157,21 +160,44 @@ dt_strcmp :
jgt %r0, %r6, .Lsame /* if (r0 > r6) goto Lsame */
jgt %r0, %r8, .Lsame /* if (r0 > r8) goto Lsame */
+ mov %r8, %r0
- ldxdw %r4, [%fp+-8]
- add %r4, %r0
- ldxb %r4, [%r4+0] /* s[r0] */
- and %r4, 0xff
+ jset %r9, 1, .Ls_is_dptr
+ ldxdw %r6, [%fp+-24] /* s = tmp1 */
- ldxdw %r5, [%fp+-16]
- add %r5, %r0
- ldxb %r5, [%r5+0] /* t[r0] */
- and %r5, 0xff
+ mov %r1, %r6
+ lddw %r2, STRSZ
+ ldxdw %r3, [%fp+-8]
+ call BPF_FUNC_probe_read_str /* bpf_probe_read_str(tmp1, r8, s) */
+ ja .Lis_t_dptr
+.Ls_is_dptr:
+ ldxdw %r6, [%fp+-8] /* Load s */
+
+.Lis_t_dptr:
+ jset %r9, 2, .Lt_is_dptr
+ ldxdw %r7, [%fp+-32] /* t = tmp2 */
+
+ mov %r1, %r7
+ lddw %r2, STRSZ
+ ldxdw %r3, [%fp+-16]
+ call BPF_FUNC_probe_read_str /* bpf_probe_read_str(tmp2, r8, t) */
+ ja .Lflags_done
+.Lt_is_dptr:
+ ldxdw %r7, [%fp+-16] /* Load t */
+.Lflags_done:
+
+ add %r6, %r8
+ ldxb %r6, [%r6+0] /* s[r8] */
+ and %r6, 0xff
+
+ add %r7, %r8
+ ldxb %r7, [%r7+0] /* t[r8] */
+ and %r7, 0xff
- jle %r4, %r5, 2 /* if (s[r0] > t[r0]) return +1 */
+ jle %r6, %r7, 2 /* if (s[r8] > t[r8]) return +1 */
mov %r0, 1
exit
- jge %r4, %r5, 2 /* if (s[r0] < t[r0]) return +1 */
+ jge %r6, %r7, 2 /* if (s[r8] < t[r8]) return +1 */
mov %r0, -1
exit
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index c4e49129..62456268 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3294,12 +3294,22 @@ dt_cg_compare_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
dt_node_is_string(dnp->dn_right)) {
dt_ident_t *idp;
uint_t Lcomp = dt_irlist_label(dlp);
+ uint32_t flags = 0;
uint64_t off1, off2;
/* if either pointer is NULL, just compare pointers */
emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, dnp->dn_left->dn_reg, 0, Lcomp));
emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, dnp->dn_right->dn_reg, 0, Lcomp));
+ /*
+ * Set flags to indicate which arguments (if any) are pointers
+ * to DTrace-managed storage.
+ */
+ if (dnp->dn_left->dn_flags & DT_NF_DPTR)
+ flags |= 1;
+ if (dnp->dn_right->dn_flags & DT_NF_DPTR)
+ flags |= 2;
+
/*
* Otherwise, replace pointers with relative string values.
* Specifically, replace left with strcmp(left,right)+1 and
@@ -3318,6 +3328,7 @@ dt_cg_compare_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
emit(dlp, BPF_MOV_REG(BPF_REG_4, BPF_REG_3));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, off1));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, off2));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_5, flags));
idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_strcmp");
assert(idp != NULL);
dt_regset_xalloc(drp, BPF_REG_0);
--
2.37.2
More information about the DTrace-devel
mailing list