[DTrace-devel] [PATCH 1/3] Transition from variable-length string size to 2-byte string size
Eugene Loh
eugene.loh at oracle.com
Thu Sep 2 02:28:37 PDT 2021
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
with a few minor comments...
On 9/2/21 2:38 AM, Kris Van Hees wrote:
> The use of variable-length integers to store string sizes has turned
> out to prohibitively complex for the BPF verifier to handle. In order
to -> to be (though I suspect you've already fixed that)
Also, (both subject line and commit message), the point isn't so much
that string sizes are changing as the string-size prefixes to strings are.
> to provide string manipulation functions we have decided to transition
> away from variable-length string size prefix.
>
> This patch provides a transition to 2-byte string sizes stored ahead
> of the actual string data. A future patch will provide a more
> permanent solution.
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> @@ -850,40 +850,31 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>
> return 0;
> } else if (dt_node_is_string(dnp)) {
> - dt_ident_t *idp;
> uint_t size_ok = dt_irlist_label(dlp);
> int reg = dt_regset_alloc(drp);
>
> off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, kind,
> size, 1, pfp, arg);
>
> - /* Retrieve the length of the string. */
> + /*
> + * Retrieve the length of the string, and adjust for the
> + * terminating NUL byte and the length prefix.
> + */
> dt_cg_strlen(dlp, drp, reg, dnp->dn_reg);
> -
> - if (dt_regset_xalloc_args(drp) == -1)
> - longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> -
> - /* Determine the number of bytes used for the length. */
> - emit(dlp, BPF_MOV_REG(BPF_REG_1, reg));
> - idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_vint_size");
> - assert(idp != NULL);
> - dt_regset_xalloc(drp, BPF_REG_0);
> - emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
> -
> - /* Add length of the string (adjusted for terminating byte). */
> - emit(dlp, BPF_ALU64_IMM(BPF_ADD, reg, 1));
> - emit(dlp, BPF_ALU64_REG(BPF_ADD, BPF_REG_0, reg));
> - dt_regset_free(drp, reg);
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, reg, 1 + DT_STRLEN_BYTES));
>
> /*
> * Copy string data (varint length + string content) to the
Strike the "varint" reference. Anticipating future changes, one could
drop the parenthetical comment altogether.
> * output buffer at [%r9 + off]. The amount of bytes copied is
> * the lesser of the data size and the maximum string size.
> */
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
> emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
> - emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_0));
> - dt_regset_free(drp, BPF_REG_0);
> + emit(dlp, BPF_MOV_REG(BPF_REG_2, reg));
> + dt_regset_free(drp, reg);
> emit(dlp, BPF_BRANCH_IMM(BPF_JLT, BPF_REG_2, size, size_ok));
> emit(dlp, BPF_MOV_IMM(BPF_REG_2, size));
> emitl(dlp, size_ok,
Strictly speaking, I suppose the way the size is clipped is a bug. It
keeps room for the length prefix, at the expense of dropping the last
two chars. In light of anticipated future changes, however, I don't
think this is worth fixing.
More information about the DTrace-devel
mailing list