[DTrace-devel] [PATCH] Add support for hton and ntoh subroutines
Kris Van Hees
kris.van.hees at oracle.com
Wed Jul 7 08:33:59 PDT 2021
Before deliving into this...
Did you take a look at the BPF_TO_BE and BPF_TO_LE instructions that BPF
provides as part of its ALUL64 support? From what I can see, that ought to
do most of what you are implementing here?
On Fri, Jul 02, 2021 at 12:39:59AM -0400, eugene.loh at oracle.com wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> libdtrace/dt_cg.c | 172 +++++++++++++++++++++++-
> test/unittest/dif/htonl.d | 1 -
> test/unittest/dif/htonll.d | 1 -
> test/unittest/dif/htons.d | 1 -
> test/unittest/funcs/tst.hton2.aarch64.r | 7 +
> test/unittest/funcs/tst.hton2.d | 28 ++++
> test/unittest/funcs/tst.hton2.x86_64.r | 7 +
> 7 files changed, 208 insertions(+), 9 deletions(-)
> create mode 100644 test/unittest/funcs/tst.hton2.aarch64.r
> create mode 100644 test/unittest/funcs/tst.hton2.d
> create mode 100644 test/unittest/funcs/tst.hton2.x86_64.r
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 0caae10a..be3a4a96 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -3283,6 +3283,166 @@ dt_cg_subr_strlen(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> TRACE_REGSET(" subr-strlen:End ");
> }
>
> +#ifdef _BIG_ENDIAN
> +static void
> +dt_cg_subr_htons(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + /* keep only lowest 16 bits */
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + dnp->dn_reg = dnp->dn_args->dn_reg;
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, dnp->dn_reg, 0xffff));
> +}
> +
> +static void
> +dt_cg_subr_htonl(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + /* keep only lowest 32 bits */
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + dnp->dn_reg = dnp->dn_args->dn_reg;
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, dnp->dn_reg, 32));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, dnp->dn_reg, 32));
> +}
> +
> +static void
> +dt_cg_subr_htonll(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + dnp->dn_reg = dnp->dn_args->dn_reg;
> +}
> +#else
> +static void
> +dt_cg_subr_htons(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + int dst, src, tmp;
> +
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + src = dnp->dn_args->dn_reg;
> + dst = dt_regset_alloc(drp);
> + tmp = dt_regset_alloc(drp);
> + if (dst == -1 || tmp == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + /* move bits 8-15 to bits 0-7 */
> + emit(dlp, BPF_MOV_REG(dst, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, dst, 48));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, dst, 56));
> +
> + /* add bits 0-7 at bits 8-15 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 56));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 48));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + dnp->dn_reg = dst;
> + dt_regset_free(drp, tmp);
> + dt_regset_free(drp, src);
> +}
> +
> +static void
> +dt_cg_subr_htonl(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + int dst, src, tmp;
> +
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + src = dnp->dn_args->dn_reg;
> + dst = dt_regset_alloc(drp);
> + tmp = dt_regset_alloc(drp);
> + if (dst == -1 || tmp == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + /* move bits 24-31 to bits 0-7 */
> + emit(dlp, BPF_MOV_REG(dst, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, dst, 24));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, dst, 0xff));
> +
> + /* add bits 16-23 at bits 8-15 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 8));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff00));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 8-15 at bits 16-23 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff00));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 8));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 0-7 at bits 24-31 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 24));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + dnp->dn_reg = dst;
> + dt_regset_free(drp, tmp);
> + dt_regset_free(drp, src);
> +}
> +
> +static void
> +dt_cg_subr_htonll(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + int dst, src, tmp;
> +
> + dt_cg_node(dnp->dn_args, dlp, drp);
> + src = dnp->dn_args->dn_reg;
> + dst = dt_regset_alloc(drp);
> + tmp = dt_regset_alloc(drp);
> + if (dst == -1 || tmp == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + /* move bits 56-63 to bits 0-7 */
> + emit(dlp, BPF_MOV_REG(dst, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, dst, 56));
> +
> + /* add bits 48-55 at bits 8-15 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 40));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff00));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 40-47 at bits 16-23 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 24));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff0000));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 32-39 at bits 24-31 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 16));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff0000));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 8));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 24-31 at bits 32-39 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_RSH, tmp, 8));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff0000));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 16));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 16-23 at bits 40-47 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff0000));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 24));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 8-15 at bits 48-55 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_AND, tmp, 0xff00));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 40));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + /* add bits 0-7 at bits 56-63 */
> + emit(dlp, BPF_MOV_REG(tmp, src));
> + emit(dlp, BPF_ALU64_IMM(BPF_LSH, tmp, 56));
> + emit(dlp, BPF_ALU64_REG(BPF_ADD, dst, tmp));
> +
> + dnp->dn_reg = dst;
> + dt_regset_free(drp, tmp);
> + dt_regset_free(drp, src);
> +}
> +#endif
> +
> typedef void dt_cg_subr_f(dt_node_t *, dt_irlist_t *, dt_regset_t *);
>
> static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
> @@ -3321,12 +3481,12 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
> [DIF_SUBR_SUBSTR] = NULL,
> [DIF_SUBR_INDEX] = &dt_cg_subr_index,
> [DIF_SUBR_RINDEX] = NULL,
> - [DIF_SUBR_HTONS] = NULL,
> - [DIF_SUBR_HTONL] = NULL,
> - [DIF_SUBR_HTONLL] = NULL,
> - [DIF_SUBR_NTOHS] = NULL,
> - [DIF_SUBR_NTOHL] = NULL,
> - [DIF_SUBR_NTOHLL] = NULL,
> + [DIF_SUBR_HTONS] = &dt_cg_subr_htons,
> + [DIF_SUBR_HTONL] = &dt_cg_subr_htonl,
> + [DIF_SUBR_HTONLL] = &dt_cg_subr_htonll,
> + [DIF_SUBR_NTOHS] = &dt_cg_subr_htons,
> + [DIF_SUBR_NTOHL] = &dt_cg_subr_htonl,
> + [DIF_SUBR_NTOHLL] = &dt_cg_subr_htonll,
> [DIF_SUBR_INET_NTOP] = NULL,
> [DIF_SUBR_INET_NTOA] = NULL,
> [DIF_SUBR_INET_NTOA6] = NULL,
> diff --git a/test/unittest/dif/htonl.d b/test/unittest/dif/htonl.d
> index 142fccd0..410bc135 100644
> --- a/test/unittest/dif/htonl.d
> +++ b/test/unittest/dif/htonl.d
> @@ -1,5 +1,4 @@
> /* @@runtest-opts: -C */
> -/* @@xfail: dtv2 */
>
> #include <endian.h>
>
> diff --git a/test/unittest/dif/htonll.d b/test/unittest/dif/htonll.d
> index 5705b462..79828736 100644
> --- a/test/unittest/dif/htonll.d
> +++ b/test/unittest/dif/htonll.d
> @@ -1,5 +1,4 @@
> /* @@runtest-opts: -C */
> -/* @@xfail: dtv2 */
>
> #include <endian.h>
>
> diff --git a/test/unittest/dif/htons.d b/test/unittest/dif/htons.d
> index ad09f324..97a4534c 100644
> --- a/test/unittest/dif/htons.d
> +++ b/test/unittest/dif/htons.d
> @@ -1,5 +1,4 @@
> /* @@runtest-opts: -C */
> -/* @@xfail: dtv2 */
>
> #include <endian.h>
>
> diff --git a/test/unittest/funcs/tst.hton2.aarch64.r b/test/unittest/funcs/tst.hton2.aarch64.r
> new file mode 100644
> index 00000000..5ca2adb8
> --- /dev/null
> +++ b/test/unittest/funcs/tst.hton2.aarch64.r
> @@ -0,0 +1,7 @@
> +f0de
> +f0debc9a
> +f0debc9a78563412
> +f0de
> +f0debc9a
> +f0debc9a78563412
> +
> diff --git a/test/unittest/funcs/tst.hton2.d b/test/unittest/funcs/tst.hton2.d
> new file mode 100644
> index 00000000..a1a506ac
> --- /dev/null
> +++ b/test/unittest/funcs/tst.hton2.d
> @@ -0,0 +1,28 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2021, 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.
> + */
> +
> +/*
> + * ASSERTION: Test network byte-ordering routines.
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> + printf("%x\n", htons (0x123456789abcdef0ll));
> + printf("%x\n", htonl (0x123456789abcdef0ll));
> + printf("%x\n", htonll(0x123456789abcdef0ll));
> + printf("%x\n", ntohs (0x123456789abcdef0ll));
> + printf("%x\n", ntohl (0x123456789abcdef0ll));
> + printf("%x\n", ntohll(0x123456789abcdef0ll));
> + exit(0);
> +}
> +
> +ERROR
> +{
> + exit(1);
> +}
> diff --git a/test/unittest/funcs/tst.hton2.x86_64.r b/test/unittest/funcs/tst.hton2.x86_64.r
> new file mode 100644
> index 00000000..5ca2adb8
> --- /dev/null
> +++ b/test/unittest/funcs/tst.hton2.x86_64.r
> @@ -0,0 +1,7 @@
> +f0de
> +f0debc9a
> +f0debc9a78563412
> +f0de
> +f0debc9a
> +f0debc9a78563412
> +
> --
> 2.18.4
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list