[DTrace-devel] [PATCH] Fix length stored by strjoin() and optimise the implementation
Eugene Loh
eugene.loh at oracle.com
Mon Nov 15 22:26:27 UTC 2021
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
You say "Fix length stored by strjoin()." So the commit message should
say what was wrong, and the patch should add a test to show that the
problem was fixed.
Also,
On 11/15/21 12:32 PM, Kris Van Hees via DTrace-devel wrote:
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
> bpf/strjoin.S | 63 +++++++++++++++++++++++++++++----------------------
> 1 file changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/bpf/strjoin.S b/bpf/strjoin.S
> index da7afa3e..2f78695a 100644
> --- a/bpf/strjoin.S
> +++ b/bpf/strjoin.S
> @@ -19,39 +19,48 @@ dt_strjoin:
> mov %r7, %r2 /* %r7 = s1 */
> mov %r8, %r3 /* %r8 = s2 */
>
> - mov %r1, %r7
> - call dt_strlen
> - mov %r6, %r0 /* len = dt_strlen(s1) */
> - add %r7, DT_STRLEN_BYTES /* s1 += 2 */
> -
> - mov %r1, %r8
> - call dt_strlen
> - add %r6, %r0 /* len += dt_strlen(s2) */
> - add %r8, DT_STRLEN_BYTES /* s2 += 2 */
> -
> - mov %r1, %r6
> - mov %r2, %r9
> - call dt_strlen_store /* dt_strlen_store(len, dst) */
> - add %r9, DT_STRLEN_BYTES /* dst += 2 */
> -
> lddw %r6, STRSZ
> - add %r6, 1
> - and %r6, 0xffffffff /* len = (STRSZ + 1) & 0xffffffff */
> + add %r6, 1 /* cnt = STRSZ + 1 */
>
> - mov %r1, %r9
> + add %r1, DT_STRLEN_BYTES /* dst is in %r1 already */
> mov %r2, %r6
> mov %r3, %r7
> - call BPF_FUNC_probe_read_str /* cnt = bpf_probe_read_str(dst, len s1) */
> - jslt %r0, 0, .L1 /* if (cnt < 0) goto .L1 */
> - jslt %r0, 1, .L2 /* if (cnt < 1) goto .L2 */
> - sub %r0, 1 /* cnt-- */
> - add %r9, %r0 /* dst += cnt */
> - sub %r6, %r0 /* len -= cnt */
> -.L2:
> + add %r3, DT_STRLEN_BYTES
> + call BPF_FUNC_probe_read_str /*
> + * rc = probe_read_str(
> + * &dst[DT_STRLEN_BYTES],
> + * cnt,
> + * &s1[DT_STRLEN_BYTES]);
> + */
> + jslt %r0, 0, .Lexit /* if (rc < 0) goto .Lexit; */
> + mov %r7, %r0 /* len = rc */
> + jslt %r7, 1, .Ls2_only /* if (len < 1) goto .Ls2_only; */
After the probe_read_str() call, the return value cannot be 0. Either it
is negative (error) or it is strictly positive. So, the first test
might as well be "jsle". Then the second test (and the Ls2_only label)
are no longer needed.
Now, let's say probe_read_str() errors out. Then we silently return
garbage? Are we happy with that? (Maybe we are. I don't know.)
For comments regarding instructions with signed conditionals, might as
well use (e.g.) "s<", "s<=", and the like.
> + sub %r7, 1 /* len-- */
> + jsge %r7, %r6, .Lset_len /* if (len >= cnt) goto .Lset_len; */
Actually, at this stage, we know len<cnt. Even the BPF verifier knows
this. So the test and the Lset_len label can be dropped.
> +
> +.Ls2_only:
> mov %r1, %r9
> + add %r1, DT_STRLEN_BYTES
> + add %r1, %r7
> mov %r2, %r6
> + sub %r2, %r7
> mov %r3, %r8
> - call BPF_FUNC_probe_read_str /* bpf_probe_read_str(dst, len, s2 */
> -.L1:
> + add %r3, DT_STRLEN_BYTES
> + call BPF_FUNC_probe_read_str /*
> + * rc = probe_read_str(
> + * &dst[DT_STRLEN_BYTES + len],
> + * cnt - len,
> + * &s2[DT_STRLEN_BYTES]);
> + */
> + jslt %r0, 0, .Lexit /* if (rc < 0) goto .Lset_len; */
> + add %r7, %r0
> + sub %r7, 1 /* len += rc - 1 */
> +
> +.Lset_len:
> + mov %r1, %r7
> + mov %r2, %r9
> + call dt_strlen_store /* dt_strlen_store(len - 1, dst) */
> +
> +.Lexit:
> exit
> .size dt_strjoin, .-dt_strjoin
More information about the DTrace-devel
mailing list