[DTrace-devel] [PATCH] Add support for uregs[]
Kris Van Hees
kris.van.hees at oracle.com
Mon Feb 20 06:10:18 UTC 2023
On Wed, Feb 15, 2023 at 03:22:05PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> The uregs[] essentially access (struct pt_regs) for the current task.
> Therefore, we use the combination of BPF helper functions
> bpf_task_pt_regs(bpf_get_current_task_btf()) to access pt_regs.
>
> Note that older kernels might not support these helper functions.
> So dt_bpf_init_helpers() checks, and if the needed functions are
> missing an error results.
>
> One place to put uregs[] support is in bpf/get_bvar.c. On the other
> hand, that means that the build system needs a gcc-bpf-unknown-none
> that knows about these functions. So, just generate the code ourselves
> to call the two helper functions; this is not much more difficult
> than calling dt_get_bvar().
>
> Further note that the documented symbolic indices to uregs[] seem
> incorrect. For x86, R_UESP is documented but not defined, and there
> are many more indices that are defined but not documented. For ARM,
> the documented indices bear little resemblance to the defined (and
> sensible!) values.
>
> The support for symbolic indices to uregs[] on x86 mimics that found
> in the legacy DTrace port to Linux -- that is, dtrace_getreg() from
> kernel code arch/x86/dtrace/dtrace_isa_x86_64.c . The logic is
> convoluted and possibly incorrect. Some uregs[] indices do not read
> from (struct pt_regs) but from task->thread.*, complicating the
> implementation. This matter warrants further attention, but for now
> mimicking the legacy port seems sufficient.
>
> For the time being, there is no annotating disassembly with "uregs".
> This can be added back in a future patch once other dust has settled.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
> libdtrace/arm64/regs.d | 6 +-
> libdtrace/dt_bpf.c | 2 +
> libdtrace/dt_cg.c | 203 ++++++++++++++-
> test/demo/builtin/uregs.sparc64.aarch64.x | 2 -
> test/demo/builtin/uregs.sparc64.d | 233 ------------------
> test/demo/builtin/uregs.sparc64.x86_64.x | 2 -
> test/demo/builtin/uregs.x86_64.aarch64.x | 2 -
> test/demo/builtin/uregs.x86_64.d | 76 ------
> test/demo/builtin/uregs.x86_64.sparc64.x | 2 -
> .../arrays/err.D_PROTO_ARG.uregs_variable.d | 19 ++
> .../arrays/err.D_PROTO_ARG.uregs_variable.r | 4 +
> .../err.D_UNKNOWN.uregs_badkernelversion.d | 19 ++
> .../err.D_UNKNOWN.uregs_badkernelversion.r | 2 +
> .../err.D_UNKNOWN.uregs_badkernelversion.x | 13 +
> .../err.D_UNKNOWN.uregs_toobig.aarch64.d | 20 ++
> .../err.D_UNKNOWN.uregs_toobig.aarch64.r | 2 +
> .../err.D_UNKNOWN.uregs_toobig.aarch64.x | 4 +
> .../err.D_UNKNOWN.uregs_toobig.x86_64.d | 20 ++
> .../err.D_UNKNOWN.uregs_toobig.x86_64.r | 2 +
> .../err.D_UNKNOWN.uregs_toobig.x86_64.x | 4 +
> test/unittest/arrays/tst.uregsarray-check.sh | 121 +++++++++
> test/unittest/arrays/tst.uregsarray-check.x | 13 +
> .../arrays/tst.uregsarray-constants.aarch64.d | 56 +++++
> .../arrays/tst.uregsarray-constants.aarch64.r | 2 +
> .../arrays/tst.uregsarray-constants.aarch64.x | 4 +
> .../arrays/tst.uregsarray-constants.x86_64.d | 44 ++++
> .../arrays/tst.uregsarray-constants.x86_64.r | 2 +
> .../arrays/tst.uregsarray-constants.x86_64.x | 4 +
> test/unittest/arrays/tst.uregsarray.arm64.d | 3 +-
> test/unittest/arrays/tst.uregsarray.arm64.x | 15 +-
> test/unittest/arrays/tst.uregsarray.d | 4 +-
> test/unittest/arrays/tst.uregsarray.x | 13 +
> test/unittest/arrays/tst.uregsarray.x86_64.d | 3 +-
> test/unittest/arrays/tst.uregsarray.x86_64.x | 15 +-
> test/unittest/disasm/tst.ann-bvar.r | 1 -
> test/unittest/disasm/tst.ann-bvar.sh | 1 -
> test/unittest/disasm/tst.vartab-bvar-uregs0.r | 2 +
> .../unittest/disasm/tst.vartab-bvar-uregs0.sh | 59 +++++
> test/unittest/disasm/tst.vartab-bvar-uregs0.x | 13 +
> test/unittest/disasm/tst.vartab-bvar.r | 1 -
> test/unittest/disasm/tst.vartab-bvar.sh | 2 +-
> test/unittest/variables/bvar/tst.uregs.d | 24 --
> 42 files changed, 679 insertions(+), 360 deletions(-)
> delete mode 100755 test/demo/builtin/uregs.sparc64.aarch64.x
> delete mode 100644 test/demo/builtin/uregs.sparc64.d
> delete mode 100755 test/demo/builtin/uregs.sparc64.x86_64.x
> delete mode 100755 test/demo/builtin/uregs.x86_64.aarch64.x
> delete mode 100644 test/demo/builtin/uregs.x86_64.d
> delete mode 100755 test/demo/builtin/uregs.x86_64.sparc64.x
> create mode 100644 test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.d
> create mode 100644 test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.r
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.d
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.r
> create mode 100755 test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.x
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.d
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.r
> create mode 100755 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.x
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.d
> create mode 100644 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.r
> create mode 100755 test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.x
> create mode 100755 test/unittest/arrays/tst.uregsarray-check.sh
> create mode 100755 test/unittest/arrays/tst.uregsarray-check.x
> create mode 100644 test/unittest/arrays/tst.uregsarray-constants.aarch64.d
> create mode 100644 test/unittest/arrays/tst.uregsarray-constants.aarch64.r
> create mode 100755 test/unittest/arrays/tst.uregsarray-constants.aarch64.x
> create mode 100644 test/unittest/arrays/tst.uregsarray-constants.x86_64.d
> create mode 100644 test/unittest/arrays/tst.uregsarray-constants.x86_64.r
> create mode 100755 test/unittest/arrays/tst.uregsarray-constants.x86_64.x
> create mode 100755 test/unittest/arrays/tst.uregsarray.x
> create mode 100644 test/unittest/disasm/tst.vartab-bvar-uregs0.r
> create mode 100755 test/unittest/disasm/tst.vartab-bvar-uregs0.sh
> create mode 100755 test/unittest/disasm/tst.vartab-bvar-uregs0.x
> delete mode 100644 test/unittest/variables/bvar/tst.uregs.d
>
> diff --git a/libdtrace/arm64/regs.d b/libdtrace/arm64/regs.d
> index 56fc461a..e47f8cfc 100644
> --- a/libdtrace/arm64/regs.d
> +++ b/libdtrace/arm64/regs.d
> @@ -67,11 +67,11 @@ inline int R_X29 = 29 ;
> inline int R_X30 = 30 ;
> #pragma D binding "1.0" R_X30
>
> -inline int R_SP = 32 ;
> +inline int R_SP = 31 ;
> #pragma D binding "1.0" R_SP
> -inline int R_PC = 33 ;
> +inline int R_PC = 32 ;
> #pragma D binding "1.0" R_PC
> -inline int R_PSTATE = 34 ;
> +inline int R_PSTATE = 33 ;
> #pragma D binding "1.0" R_PSTATE
>
> inline int R_FP = R_X29;
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index f0f46c5c..80383e25 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -360,6 +360,8 @@ dt_bpf_init_helpers(dtrace_hdl_t *dtp)
> BPF_HELPER_MAP(probe_read_user_str, probe_read_str);
> BPF_HELPER_MAP(probe_read_kernel, probe_read);
> BPF_HELPER_MAP(probe_read_kernel_str, probe_read_str);
> + BPF_HELPER_MAP(get_current_task_btf, unspec);
> + BPF_HELPER_MAP(task_pt_regs, unspec);
> #undef BPF_HELPER_MAP
> }
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 50846942..eec7b243 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -3944,6 +3944,201 @@ dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> TRACE_REGSET(" assoc_op: End ");
> }
>
> +#if defined(__amd64)
> +/* 64-bit programs on x86 */
> +/* adapted from DTv1 kernel code arch/x86/dtrace/dtrace_isa_x86_64.c dtrace_getreg() */
> +
> +/*
> + * dtrace_isa_x86_64.c defines REG_*.
> + * We call them DT_CG_REG_*
> + * to avoid name collisions with /usr/include/sys/ucontext.h .
> + */
> +#define DT_CG_REG_TRAPNO 25
> +#define DT_CG_REG_GS 24
> +#define DT_CG_REG_FS 23
> +#define DT_CG_REG_ES 22
> +#define DT_CG_REG_DS 21
> +#define DT_CG_REG_SS 20
> +#define DT_CG_REG_RSP 19
> +#define DT_CG_REG_RFL 18
> +#define DT_CG_REG_CS 17
> +#define DT_CG_REG_RIP 16
> +#define DT_CG_REG_ERR 15
> +#define DT_CG_REG_RDI 14
> +#define DT_CG_REG_RSI 13
> +#define DT_CG_REG_RDX 12
> +#define DT_CG_REG_RCX 11
> +#define DT_CG_REG_RAX 10
> +#define DT_CG_REG_R8 9
> +#define DT_CG_REG_R9 8
> +#define DT_CG_REG_R10 7
> +#define DT_CG_REG_R11 6
> +#define DT_CG_REG_RBX 5
> +#define DT_CG_REG_RBP 4
> +#define DT_CG_REG_R12 3
> +#define DT_CG_REG_R13 2
> +#define DT_CG_REG_R14 1
> +#define DT_CG_REG_R15 0
> +
> +static void
> +dt_cg_uregs(unsigned int idx, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + int regmap[] = { DT_CG_REG_RBX, /* 0 -> EBX */
> + DT_CG_REG_RCX, /* 1 -> ECX */
> + DT_CG_REG_RDX, /* 2 -> EDX */
> + DT_CG_REG_RSI, /* 3 -> ESI */
> + DT_CG_REG_RDI, /* 4 -> EDI */
> + DT_CG_REG_RBP, /* 5 -> EBP */
> + DT_CG_REG_RAX, /* 6 -> EAX */
> + DT_CG_REG_DS, /* 7 -> DS */
> + DT_CG_REG_ES, /* 8 -> ES */
> + DT_CG_REG_FS, /* 9 -> FS */
> + DT_CG_REG_GS, /* 10 -> GS */
> + DT_CG_REG_TRAPNO, /* 11 -> TRAPNO */
> + DT_CG_REG_RIP, /* 12 -> EIP */
> + DT_CG_REG_CS, /* 13 -> CS */
> + DT_CG_REG_RFL, /* 14 -> EFL */
> + DT_CG_REG_RSP, /* 15 -> UESP */
> + DT_CG_REG_SS, /* 16 -> SS */
> + };
> + dtrace_hdl_t *dtp = yypcb->pcb_hdl;
> + ctf_file_t *cfp = dtp->dt_shared_ctf;
> + ctf_id_t type;
> + ctf_membinfo_t ctm;
> + int offset, rc;
> +
> + if (idx >= sizeof(regmap) / sizeof(int) + DT_CG_REG_GS + 1) {
> + dnerror(dnp, D_UNKNOWN, "uregs[%d]: unrecognized index\n", idx);
> + return;
> + }
> +
> + /* convert register alias index into register mapping index */
> + if (idx > DT_CG_REG_TRAPNO)
> + idx = regmap[idx - DT_CG_REG_GS - 1];
> +
> + /* look up pt_regs[] */
> + if (idx <= DT_CG_REG_SS) {
> + if (dtp->dt_bpfhelper[BPF_FUNC_get_current_task_btf] == BPF_FUNC_unspec
> + || dtp->dt_bpfhelper[BPF_FUNC_task_pt_regs] == BPF_FUNC_unspec)
> + dnerror(dnp, D_UNKNOWN, "uregs[]: pt_regs[] look up is not implemented for this kernel version\n");
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_task_btf));
> + emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_0));
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_task_pt_regs));
> + dt_regset_free_args(drp);
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, idx * sizeof(uint64_t)));
> + emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_0, 0));
> + dt_regset_free(drp, BPF_REG_0);
> + return;
> + }
> +
> + /* look up task->thread offset */
> +
> + if (!cfp)
> + assert(0); // return dt_set_errno(dtp, EDT_NOCTF);
> +
> + type = ctf_lookup_by_name(cfp, "struct task_struct");
> + if (type == CTF_ERR)
> + assert(0); // return dt_set_errno(dtp, EDT_NOCTF);
> + if (ctf_member_info(cfp, type, "thread", &ctm) == CTF_ERR)
> + assert(0); // return dt_set_errno(dtp, EDT_NOCTF);
> + offset = ctm.ctm_offset / NBBY;
> +
> + /* add the thread->member offset */
> +
> + type = ctf_lookup_by_name(cfp, "struct thread_struct");
> + if (type == CTF_ERR)
> + assert(0); // return dt_set_errno(dtp, EDT_NOCTF);
> + switch (idx) {
> + case DT_CG_REG_DS: rc = ctf_member_info(cfp, type, "ds", &ctm); break;
> + case DT_CG_REG_ES: rc = ctf_member_info(cfp, type, "es", &ctm); break;
> + case DT_CG_REG_FS: rc = ctf_member_info(cfp, type, "fsbase", &ctm); break;
> + case DT_CG_REG_GS: rc = ctf_member_info(cfp, type, "gsbase", &ctm); break;
> + case DT_CG_REG_TRAPNO: rc = ctf_member_info(cfp, type, "trap_nr", &ctm); break;
> + default: dnerror(dnp, D_UNKNOWN, "uregs[%d]: unrecognized index\n", idx);
> + }
> + if (rc == -1)
> + assert(0); // return dt_set_errno(dtp, EDT_NOCTF);
> + offset += ctm.ctm_offset / NBBY;
> +
> + /* copy task->thread.member onto the stack*/
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_task));
> + emit(dlp, BPF_MOV_REG(BPF_REG_3, BPF_REG_0));
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, offset));
> + emit(dlp, BPF_MOV_IMM(BPF_REG_2, sizeof(uint64_t)));
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_SP));
> + emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel]));
> + dt_regset_free_args(drp);
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_FP, DT_STK_SP));
> + emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_0, 0));
> + dt_regset_free(drp, BPF_REG_0);
> +}
> +
> +#undef DT_CG_REG_TRAPNO
> +#undef DT_CG_REG_GS
> +#undef DT_CG_REG_FS
> +#undef DT_CG_REG_ES
> +#undef DT_CG_REG_DS
> +#undef DT_CG_REG_SS
> +#undef DT_CG_REG_RSP
> +#undef DT_CG_REG_RFL
> +#undef DT_CG_REG_CS
> +#undef DT_CG_REG_RIP
> +#undef DT_CG_REG_ERR
> +#undef DT_CG_REG_RDI
> +#undef DT_CG_REG_RSI
> +#undef DT_CG_REG_RDX
> +#undef DT_CG_REG_RCX
> +#undef DT_CG_REG_RAX
> +#undef DT_CG_REG_R8
> +#undef DT_CG_REG_R9
> +#undef DT_CG_REG_R10
> +#undef DT_CG_REG_R11
> +#undef DT_CG_REG_RBX
> +#undef DT_CG_REG_RBP
> +#undef DT_CG_REG_R12
> +#undef DT_CG_REG_R13
> +#undef DT_CG_REG_R14
> +#undef DT_CG_REG_R15
> +
> +#elif defined(__aarch64__)
> +/* aarch64 */
> +/* adapted from DTv1 kernel code arch/arm64/dtrace/dtrace_isa_arm64.c dtrace_getreg() */
> +static void
> +dt_cg_uregs(unsigned int idx, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dtrace_hdl_t *dtp = yypcb->pcb_hdl;
> +
> + if (idx >= sizeof(struct user_pt_regs) / sizeof(uint64_t)) {
> + dnerror(dnp, D_UNKNOWN, "uregs[%d]: unrecognized index\n", idx);
> + return;
> + }
> +
> + if (dtp->dt_bpfhelper[BPF_FUNC_get_current_task_btf] == BPF_FUNC_unspec
> + || dtp->dt_bpfhelper[BPF_FUNC_task_pt_regs] == BPF_FUNC_unspec)
> + dnerror(dnp, D_UNKNOWN, "uregs[]: pt_regs[] look up is not implemented for this kernel version\n");
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_task_btf));
> + emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_0));
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_task_pt_regs));
> + dt_regset_free_args(drp);
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, idx * sizeof(uint64_t)));
> + emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_0, 0));
> + dt_regset_free(drp, BPF_REG_0);
> +}
> +#else
> +#error unknown ISA
> +#endif
> +
> /*
> * Currently, this code is only used for the args[] and uregs[] arrays.
> */
> @@ -3956,6 +4151,7 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> dt_ident_t *fidp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_get_bvar");
> size_t size;
> int n;
> + unsigned int idx;
>
> assert(dnp->dn_kind == DT_NODE_VAR);
> assert(!(idp->di_flags & (DT_IDFLG_TLS | DT_IDFLG_LOCAL)));
> @@ -3998,12 +4194,17 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> }
>
> dt_cg_node(dnp->dn_args, dlp, drp);
> + idx = dnp->dn_args->dn_value;
> dnp->dn_args->dn_value = saved;
> dnp->dn_reg = dnp->dn_args->dn_reg;
>
> + if (idp->di_id == DIF_VAR_UREGS) {
> + dt_cg_uregs(idx, dnp, dlp, drp);
> + return;
> + }
> +
> if (dt_regset_xalloc_args(drp) == -1)
> longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> -
> emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
> emit(dlp, BPF_MOV_IMM(BPF_REG_2, idp->di_id));
> emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));
> diff --git a/test/demo/builtin/uregs.sparc64.aarch64.x b/test/demo/builtin/uregs.sparc64.aarch64.x
> deleted file mode 100755
> index 5c66540d..00000000
> --- a/test/demo/builtin/uregs.sparc64.aarch64.x
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -#!/bin/sh
> -exit 2
> diff --git a/test/demo/builtin/uregs.sparc64.d b/test/demo/builtin/uregs.sparc64.d
> deleted file mode 100644
> index a2c0879f..00000000
> --- a/test/demo/builtin/uregs.sparc64.d
> +++ /dev/null
> @@ -1,233 +0,0 @@
> -/*
> - * Oracle Linux DTrace.
> - * Copyright (c) 2016, 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.
> - */
> -
> -BEGIN
> -{
> - printf("R_ASI = 0x%x\n", uregs[R_ASI]);
> -}
> -
> -BEGIN
> -{
> - printf("R_CCR = 0x%x\n", uregs[R_CCR]);
> -}
> -
> -BEGIN
> -{
> - printf("R_FP = 0x%x\n", uregs[R_FP]);
> -}
> -
> -BEGIN
> -{
> - printf("R_FPRS = 0x%x\n", uregs[R_FPRS]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G0 = 0x%x\n", uregs[R_G0]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G1 = 0x%x\n", uregs[R_G1]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G2 = 0x%x\n", uregs[R_G2]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G3 = 0x%x\n", uregs[R_G3]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G4 = 0x%x\n", uregs[R_G4]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G5 = 0x%x\n", uregs[R_G5]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G6 = 0x%x\n", uregs[R_G6]);
> -}
> -
> -BEGIN
> -{
> - printf("R_G7 = 0x%x\n", uregs[R_G7]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I0 = 0x%x\n", uregs[R_I0]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I1 = 0x%x\n", uregs[R_I1]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I2 = 0x%x\n", uregs[R_I2]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I3 = 0x%x\n", uregs[R_I3]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I4 = 0x%x\n", uregs[R_I4]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I5 = 0x%x\n", uregs[R_I5]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I6 = 0x%x\n", uregs[R_I6]);
> -}
> -
> -BEGIN
> -{
> - printf("R_I7 = 0x%x\n", uregs[R_I7]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L0 = 0x%x\n", uregs[R_L0]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L1 = 0x%x\n", uregs[R_L1]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L2 = 0x%x\n", uregs[R_L2]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L3 = 0x%x\n", uregs[R_L3]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L4 = 0x%x\n", uregs[R_L4]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L5 = 0x%x\n", uregs[R_L5]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L6 = 0x%x\n", uregs[R_L6]);
> -}
> -
> -BEGIN
> -{
> - printf("R_L7 = 0x%x\n", uregs[R_L7]);
> -}
> -
> -BEGIN
> -{
> - printf("R_NPC = 0x%x\n", uregs[R_NPC]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O0 = 0x%x\n", uregs[R_O0]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O1 = 0x%x\n", uregs[R_O1]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O2 = 0x%x\n", uregs[R_O2]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O3 = 0x%x\n", uregs[R_O3]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O4 = 0x%x\n", uregs[R_O4]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O5 = 0x%x\n", uregs[R_O5]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O6 = 0x%x\n", uregs[R_O6]);
> -}
> -
> -BEGIN
> -{
> - printf("R_O7 = 0x%x\n", uregs[R_O7]);
> -}
> -
> -BEGIN
> -{
> - printf("R_PC = 0x%x\n", uregs[R_PC]);
> -}
> -
> -BEGIN
> -{
> - printf("R_PS = 0x%x\n", uregs[R_PS]);
> -}
> -
> -BEGIN
> -{
> - printf("R_R0 = 0x%x\n", uregs[R_R0]);
> -}
> -
> -BEGIN
> -{
> - printf("R_R1 = 0x%x\n", uregs[R_R1]);
> -}
> -
> -BEGIN
> -{
> - printf("R_SP = 0x%x\n", uregs[R_SP]);
> -}
> -
> -BEGIN
> -{
> - printf("R_Y = 0x%x\n", uregs[R_Y]);
> -}
> -
> -BEGIN
> -{
> - printf("R_nPC = 0x%x\n", uregs[R_nPC]);
> - exit(0);
> -}
> -
> -ERROR
> -{
> - printf("uregs access failed.\n");
> - exit(1);
> -}
> diff --git a/test/demo/builtin/uregs.sparc64.x86_64.x b/test/demo/builtin/uregs.sparc64.x86_64.x
> deleted file mode 100755
> index 5c66540d..00000000
> --- a/test/demo/builtin/uregs.sparc64.x86_64.x
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -#!/bin/sh
> -exit 2
> diff --git a/test/demo/builtin/uregs.x86_64.aarch64.x b/test/demo/builtin/uregs.x86_64.aarch64.x
> deleted file mode 100755
> index 5c66540d..00000000
> --- a/test/demo/builtin/uregs.x86_64.aarch64.x
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -#!/bin/sh
> -exit 2
> diff --git a/test/demo/builtin/uregs.x86_64.d b/test/demo/builtin/uregs.x86_64.d
> deleted file mode 100644
> index 49886dea..00000000
> --- a/test/demo/builtin/uregs.x86_64.d
> +++ /dev/null
> @@ -1,76 +0,0 @@
> -/*
> - * Oracle Linux DTrace.
> - * Copyright (c) 2011, 2020, 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.
> - */
> -
> -/* @@xfail: dtv2 */
> -BEGIN
> -{
> - printf("R_GS = 0x%x\n", uregs[R_GS]);
> -}
> -BEGIN
> -{
> - printf("R_ES = 0x%x\n", uregs[R_ES]);
> -}
> -BEGIN
> -{
> - printf("R_DS = 0x%x\n", uregs[R_DS]);
> -}
> -BEGIN
> -{
> - printf("R_RDI = 0x%x\n", uregs[R_RDI]);
> -}
> -BEGIN
> -{
> - printf("R_RSI = 0x%x\n", uregs[R_RSI]);
> -}
> -BEGIN
> -{
> - printf("R_RBP = 0x%x\n", uregs[R_RBP]);
> -}
> -BEGIN
> -{
> - printf("R_RBX = 0x%x\n", uregs[R_RBX]);
> -}
> -BEGIN
> -{
> - printf("R_RDX = 0x%x\n", uregs[R_RDX]);
> -}
> -BEGIN
> -{
> - printf("R_RCX = 0x%x\n", uregs[R_RCX]);
> -}
> -BEGIN
> -{
> - printf("R_RAX = 0x%x\n", uregs[R_RAX]);
> -/* printf("R_TRAPNO = 0x%x\n", uregs[R_TRAPNO]); */
> -/* printf("R_ERR = 0x%x\n", uregs[R_ERR]); */
> -}
> -BEGIN
> -{
> - printf("R_RIP = 0x%x\n", uregs[R_RIP]);
> -}
> -BEGIN
> -{
> - printf("R_CS = 0x%x\n", uregs[R_CS]);
> -}
> -BEGIN
> -{
> - printf("R_EFL = 0x%x\n", uregs[R_EFL]);
> -}
> -BEGIN
> -{
> - printf("R_RSP = 0x%x\n", uregs[R_RSP]);
> -}
> -BEGIN
> -{
> - printf("R_SS = 0x%x\n", uregs[R_SS]);
> - exit(0);
> -}
> -ERROR
> -{
> - printf("uregs access failed.\n");
> - exit(1);
> -}
> diff --git a/test/demo/builtin/uregs.x86_64.sparc64.x b/test/demo/builtin/uregs.x86_64.sparc64.x
> deleted file mode 100755
> index 5c66540d..00000000
> --- a/test/demo/builtin/uregs.x86_64.sparc64.x
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -#!/bin/sh
> -exit 2
> diff --git a/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.d b/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.d
> new file mode 100644
> index 00000000..dc57f8d3
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.d
> @@ -0,0 +1,19 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: uregs[] must have a constant index.
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +BEGIN
> +{
> + i = R_SP;
> + trace(uregs[i]);
> + exit(1);
> +}
> diff --git a/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.r b/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.r
> new file mode 100644
> index 00000000..2349e17e
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/arrays/err.D_PROTO_ARG.uregs_variable.d: [D_PROTO_ARG] line 17: uregs[ ] argument #1 is incompatible with prototype:
> + prototype: integer constant
> + argument: int
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.d b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.d
> new file mode 100644
> index 00000000..ed375348
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.d
> @@ -0,0 +1,19 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: uregs[] not supported on old kernels.
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +BEGIN
> +{
> + trace(uregs[R_SP]);
> + exit(1);
> +}
> +
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.r b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.r
> new file mode 100644
> index 00000000..3fb2c007
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.d: [D_UNKNOWN] line 16: uregs[]: pt_regs[] look up is not implemented for this kernel version
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.x b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.x
> new file mode 100755
> index 00000000..5a59adee
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.x
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -lt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -lt 15 ]; then
> + exit 0
> +fi
> +
> +echo "no UNKNOWN-uregs problem on newer kernels"
> +exit 2
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.d b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.d
> new file mode 100644
> index 00000000..f022984e
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: Check the constants used to access uregs[].
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> + trace(uregs[R_PSTATE + 1]);
> + exit(0);
> +}
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.r b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.r
> new file mode 100644
> index 00000000..79042461
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.d: [D_UNKNOWN] line 18: uregs[34]: unrecognized index
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.x b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.x
> new file mode 100755
> index 00000000..36074cb2
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.aarch64.x
> @@ -0,0 +1,4 @@
> +#!/bin/sh
> +
> +[ `uname -m` = "aarch64" ] && exit 0
> +exit 2
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.d b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.d
> new file mode 100644
> index 00000000..ea5c5db6
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: Check the constants used to access uregs[].
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> + trace(uregs[42]);
> + exit(0);
> +}
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.r b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.r
> new file mode 100644
> index 00000000..d8e3fb73
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.d: [D_UNKNOWN] line 18: uregs[42]: unrecognized index
> diff --git a/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.x b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.x
> new file mode 100755
> index 00000000..69e36e70
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_toobig.x86_64.x
> @@ -0,0 +1,4 @@
> +#!/bin/sh
> +
> +[ `uname -m` = "x86_64" ] && exit 0
> +exit 2
> diff --git a/test/unittest/arrays/tst.uregsarray-check.sh b/test/unittest/arrays/tst.uregsarray-check.sh
> new file mode 100755
> index 00000000..b672666e
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-check.sh
> @@ -0,0 +1,121 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2023, 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.
> +#
> +
> +dtrace=$1
> +CC=/usr/bin/gcc
> +CFLAGS=
> +
> +DIRNAME="$tmpdir/arrays-uregsarray-check.$$.$RANDOM"
> +mkdir -p $DIRNAME
> +cd $DIRNAME
> +
> +# compile USDT provider
> +
> +cat > prov.d <<EOF
> +provider test_prov {
> + probe go();
> +};
> +EOF
> +
> +$dtrace -h -s prov.d
> +if [ $? -ne 0 ]; then
> + echo "failed to generate header file" >& 2
> + exit 1
> +fi
> +
> +# compile instrumented user test program
> +
> +cat > test.c <<EOF
> +#include <stdio.h>
> +
> +#include <sys/types.h>
> +#include "prov.h"
> +
> +int main(int c, char **v) {
> + int local_variable = 10;
> +
> + printf("instructions start at %p\n", &main);
> + printf("local variable at %p\n", &local_variable);
> + TEST_PROV_GO();
> + return 0;
> +}
> +EOF
> +
> +${CC} ${CFLAGS} -c test.c
> +if [ $? -ne 0 ]; then
> + echo "failed to compile test.c" >& 2
> + exit 1
> +fi
> +$dtrace -G -s prov.d test.o
> +if [ $? -ne 0 ]; then
> + echo "failed to create DOF" >& 2
> + exit 1
> +fi
> +${CC} ${CFLAGS} -o test test.o prov.o
> +if [ $? -ne 0 ]; then
> + echo "failed to link final executable" >& 2
> + exit 1
> +fi
> +
> +# run DTrace
> +
> +$dtrace -c ./test -qn '
> +test_prov$target:::
> +{
> + printf("DTrace has PC %x and SP %x\n", uregs[R_PC], uregs[R_SP]);
> + exit(0);
> +}' -o D.out > C.out
> +
> +if [ $? -ne 0 ]; then
> + echo DTrace ERROR
> + cat D.out C.out
> + exit 1
> +fi
> +
> +# post processing
> +
> +awk '
> +BEGIN { DTrace_PC = DTrace_SP = instructions = local_variable = -1 }
> +
> +# the first file has DTrace output
> +NR == FNR && /^DTrace has PC / { DTrace_PC = "0x"$4; DTrace_SP = "0x"$7; next; }
> +
> +# the second file has output from the C program
> +NR != FNR && /^instructions start at / { instructions = $4; next; }
> +NR != FNR && /^local variable at / { local_variable = $4; next; }
> +
> +END {
> + if ( DTrace_PC <= 0 ||
> + DTrace_SP <= 0 ||
> + instructions <= 0 ||
> + local_variable <= 0 ) {
> + print "ERROR: did not see all output in post-processing";
> + exit 1;
> + }
> +
> + # the PC must be early in the reported function
> + offset = strtonum(DTrace_PC) - strtonum(instructions);
> + print "PC offset is", DTrace_PC, " -", instructions, "=", offset;
> + if ( offset < 0 || offset > 100 ) {
> + print "ERROR: instruction offset is unreasonable";
> + exit 1;
> + }
> +
> + # the local variable address must be a little higher than the SP
> + offset = strtonum(local_variable) - strtonum(DTrace_SP);
> + print "stack variable offset is", local_variable, " -", DTrace_SP, "=", offset;
> + if ( offset < 0 || offset > 100 ) {
> + print "ERROR: stack variable offset is unreasonable";
> + exit 1;
> + }
> +
> + print "success: both offsets are reasonable";
> + exit 0;
> +}' D.out C.out
> +
> +exit $?
> diff --git a/test/unittest/arrays/tst.uregsarray-check.x b/test/unittest/arrays/tst.uregsarray-check.x
> new file mode 100755
> index 00000000..b5ce6a1d
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-check.x
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -gt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -ge 15 ]; then
> + exit 0
> +fi
> +
> +echo "no uregs on older kernels"
> +exit 1
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.aarch64.d b/test/unittest/arrays/tst.uregsarray-constants.aarch64.d
> new file mode 100644
> index 00000000..a8c3a7d9
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.aarch64.d
> @@ -0,0 +1,56 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: Check the constants used to access uregs[].
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> + printf(" %d", R_X0);
> + printf(" %d", R_X1);
> + printf(" %d", R_X2);
> + printf(" %d", R_X3);
> + printf(" %d", R_X4);
> + printf(" %d", R_X5);
> + printf(" %d", R_X6);
> + printf(" %d", R_X7);
> + printf(" %d", R_X8);
> + printf(" %d", R_X9);
> + printf(" %d", R_X10);
> + printf(" %d", R_X11);
> + printf(" %d", R_X12);
> + printf(" %d", R_X13);
> + printf(" %d", R_X14);
> + printf(" %d", R_X15);
> + printf(" %d", R_X16);
> + printf(" %d", R_X17);
> + printf(" %d", R_X18);
> + printf(" %d", R_X19);
> + printf(" %d", R_X20);
> + printf(" %d", R_X21);
> + printf(" %d", R_X22);
> + printf(" %d", R_X23);
> + printf(" %d", R_X24);
> + printf(" %d", R_X25);
> + printf(" %d", R_X26);
> + printf(" %d", R_X27);
> + printf(" %d", R_X28);
> + printf(" %d", R_X29);
> + printf(" %d", R_X30);
> + printf(" %d", R_SP);
> + printf(" %d", R_PC);
> + printf(" %d", R_PSTATE);
> + printf(" %d", R_FP);
> + printf("\n");
> +
> + exit(0);
> +}
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.aarch64.r b/test/unittest/arrays/tst.uregsarray-constants.aarch64.r
> new file mode 100644
> index 00000000..8b160812
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.aarch64.r
> @@ -0,0 +1,2 @@
> + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 29
> +
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.aarch64.x b/test/unittest/arrays/tst.uregsarray-constants.aarch64.x
> new file mode 100755
> index 00000000..36074cb2
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.aarch64.x
> @@ -0,0 +1,4 @@
> +#!/bin/sh
> +
> +[ `uname -m` = "aarch64" ] && exit 0
> +exit 2
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.x86_64.d b/test/unittest/arrays/tst.uregsarray-constants.x86_64.d
> new file mode 100644
> index 00000000..84ecd358
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.x86_64.d
> @@ -0,0 +1,44 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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: Check the constants used to access uregs[].
> + *
> + * SECTION: User Process Tracing/uregs Array
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> + printf(" %d", R_PC);
> + printf(" %d", R_SP);
> + printf(" %d", R_R0);
> + printf(" %d", R_R1);
> + printf(" %d", R_CS);
> + printf(" %d", R_GS);
> + printf(" %d", R_ES);
> + printf(" %d", R_DS);
> + printf(" %d", R_EDI);
> + printf(" %d", R_ESI);
> + printf(" %d", R_EBP);
> + printf(" %d", R_EAX);
> + printf(" %d", R_ESP);
> + printf(" %d", R_EAX);
> + printf(" %d", R_EBX);
> + printf(" %d", R_ECX);
> + printf(" %d", R_EDX);
> + printf(" %d", R_TRAPNO);
> + printf(" %d", R_ERR);
> + printf(" %d", R_EIP);
> + printf(" %d", R_CS);
> + printf(" %d", R_EFL);
> + /* printf(" %d", R_UESP); */ /* in the User's Guide, but not defined in regs.d */
> + printf(" %d", R_SS);
> + printf("\n");
> + exit(0);
> +}
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.x86_64.r b/test/unittest/arrays/tst.uregsarray-constants.x86_64.r
> new file mode 100644
> index 00000000..74766ec5
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.x86_64.r
> @@ -0,0 +1,2 @@
> + 37 40 31 25 17 24 22 21 29 28 30 31 40 31 25 26 27 25 15 37 17 39 20
> +
> diff --git a/test/unittest/arrays/tst.uregsarray-constants.x86_64.x b/test/unittest/arrays/tst.uregsarray-constants.x86_64.x
> new file mode 100755
> index 00000000..69e36e70
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.x86_64.x
> @@ -0,0 +1,4 @@
> +#!/bin/sh
> +
> +[ `uname -m` = "x86_64" ] && exit 0
> +exit 2
> diff --git a/test/unittest/arrays/tst.uregsarray.arm64.d b/test/unittest/arrays/tst.uregsarray.arm64.d
> index 87b316a5..776bca8a 100644
> --- a/test/unittest/arrays/tst.uregsarray.arm64.d
> +++ b/test/unittest/arrays/tst.uregsarray.arm64.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2023, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/arrays/tst.uregsarray.arm64.x b/test/unittest/arrays/tst.uregsarray.arm64.x
> index 36074cb2..affd405f 100755
> --- a/test/unittest/arrays/tst.uregsarray.arm64.x
> +++ b/test/unittest/arrays/tst.uregsarray.arm64.x
> @@ -1,4 +1,15 @@
> #!/bin/sh
>
> -[ `uname -m` = "aarch64" ] && exit 0
> -exit 2
> +[ `uname -m` != "aarch64" ] && exit 2
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -gt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -ge 15 ]; then
> + exit 0
> +fi
> +
> +echo "uregs[]: pt_regs[] lookup not implemented on older kernels"
> +exit 1
> diff --git a/test/unittest/arrays/tst.uregsarray.d b/test/unittest/arrays/tst.uregsarray.d
> index 0037f181..9b2a537e 100644
> --- a/test/unittest/arrays/tst.uregsarray.d
> +++ b/test/unittest/arrays/tst.uregsarray.d
> @@ -1,11 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2023, 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.
> */
> -/* @@xfail: dtv2 */
> -
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/arrays/tst.uregsarray.x b/test/unittest/arrays/tst.uregsarray.x
> new file mode 100755
> index 00000000..32e676e8
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray.x
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -gt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -ge 15 ]; then
> + exit 0
> +fi
> +
> +echo "uregs[]: pt_regs[] lookup not implemented on older kernels"
> +exit 1
> diff --git a/test/unittest/arrays/tst.uregsarray.x86_64.d b/test/unittest/arrays/tst.uregsarray.x86_64.d
> index 26137dfe..fff6bcf0 100644
> --- a/test/unittest/arrays/tst.uregsarray.x86_64.d
> +++ b/test/unittest/arrays/tst.uregsarray.x86_64.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2023, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/arrays/tst.uregsarray.x86_64.x b/test/unittest/arrays/tst.uregsarray.x86_64.x
> index 69e36e70..c5d64eaf 100755
> --- a/test/unittest/arrays/tst.uregsarray.x86_64.x
> +++ b/test/unittest/arrays/tst.uregsarray.x86_64.x
> @@ -1,4 +1,15 @@
> #!/bin/sh
>
> -[ `uname -m` = "x86_64" ] && exit 0
> -exit 2
> +[ `uname -m` != "x86_64" ] && exit 2
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -gt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -ge 15 ]; then
> + exit 0
> +fi
> +
> +echo "uregs[]: pt_regs[] lookup not implemented on older kernels"
> +exit 1
> diff --git a/test/unittest/disasm/tst.ann-bvar.r b/test/unittest/disasm/tst.ann-bvar.r
> index ec8c2c09..b514dd99 100644
> --- a/test/unittest/disasm/tst.ann-bvar.r
> +++ b/test/unittest/disasm/tst.ann-bvar.r
> @@ -29,7 +29,6 @@
> 85 0 1 0000 ffffffff call dt_get_bvar ! timestamp
> 85 0 1 0000 ffffffff call dt_get_bvar ! ucaller
> 85 0 1 0000 ffffffff call dt_get_bvar ! uid
> -85 0 1 0000 ffffffff call dt_get_bvar ! uregs
> 85 0 1 0000 ffffffff call dt_get_bvar ! ustackdepth
> 85 0 1 0000 ffffffff call dt_get_bvar ! vtimestamp
> 85 0 1 0000 ffffffff call dt_get_bvar ! walltimestamp
> diff --git a/test/unittest/disasm/tst.ann-bvar.sh b/test/unittest/disasm/tst.ann-bvar.sh
> index e53123f3..1986de66 100755
> --- a/test/unittest/disasm/tst.ann-bvar.sh
> +++ b/test/unittest/disasm/tst.ann-bvar.sh
> @@ -42,7 +42,6 @@ sdt:task::task_rename
> trace(timestamp);
> trace(ucaller);
> trace(uid);
> - trace(uregs[0]);
> trace(ustackdepth);
> trace(vtimestamp);
> trace(walltimestamp);
> diff --git a/test/unittest/disasm/tst.vartab-bvar-uregs0.r b/test/unittest/disasm/tst.vartab-bvar-uregs0.r
> new file mode 100644
> index 00000000..b1c07635
> --- /dev/null
> +++ b/test/unittest/disasm/tst.vartab-bvar-uregs0.r
> @@ -0,0 +1,2 @@
> +NAME OFFSET KND SCP FLAG TYPE
> +uregs arr glb r D type (integer) (size 8)
> diff --git a/test/unittest/disasm/tst.vartab-bvar-uregs0.sh b/test/unittest/disasm/tst.vartab-bvar-uregs0.sh
> new file mode 100755
> index 00000000..9a37f4bd
> --- /dev/null
> +++ b/test/unittest/disasm/tst.vartab-bvar-uregs0.sh
> @@ -0,0 +1,59 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2022, 2023, 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: Built-in variables should not displayed with an offset
> +# Test uregs[0] separately until it works on all kernel versions.
> +#
> +# SECTION: Variables/Scalar Variables
> +#
> +##
> +
> +dtrace=$1
> +
> +$dtrace $dt_flags -Sen '
> +sdt:task::task_rename
> +{
> + trace(uregs[0]);
> + exit(0);
> +}
> +' 2>&1 | awk '
> +BEGIN {
> + rc = 1;
> +}
> +
> +/^NAME/ && /KND SCP/ {
> + printf "%-16s %-6s %-3s %-3s %-4s %s\n",
> + "NAME", "OFFSET", "KND", "SCP","FLAG", "TYPE";
> + while (getline == 1 && NF > 0) {
> + if ($3 == "scl" || $3 == "arr") {
> + $2 = $5 = "";
> + gsub(/ +/, " ");
> + printf "%-16s %-6s %-3s %-3s %-4s", $1, "", $2, $3, $4;
> + $1 = $2 = $3 = $4 = "";
> + gsub(/ +/, " ");
> + } else {
> + $2 = $6 = "";
> + gsub(/ +/, " ");
> + printf "%-16s %-6s %-3s %-3s %-4s", $1, $2, $3, $4, $5;
> + $1 = $2 = $3 = $4 = $5 = "";
> + gsub(/ +/, " ");
> + }
> +
> + print $0;
> + rc = 0;
> + }
> +}
> +
> +END {
> + exit(rc);
> +}
> +'
> +
> +exit $?
> diff --git a/test/unittest/disasm/tst.vartab-bvar-uregs0.x b/test/unittest/disasm/tst.vartab-bvar-uregs0.x
> new file mode 100755
> index 00000000..b5ce6a1d
> --- /dev/null
> +++ b/test/unittest/disasm/tst.vartab-bvar-uregs0.x
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
This is a problem because the script is using /bin/sh and assumes that the
standard shell supports this construct. You should make the script /bin/bash.
> +
> +if [ $MAJOR -gt 5 ]; then
> + exit 0
> +fi
> +if [ $MAJOR -eq 5 -a $MINOR -ge 15 ]; then
> + exit 0
> +fi
> +
> +echo "no uregs on older kernels"
> +exit 1
> diff --git a/test/unittest/disasm/tst.vartab-bvar.r b/test/unittest/disasm/tst.vartab-bvar.r
> index 8a1c5fd2..06d7c52b 100644
> --- a/test/unittest/disasm/tst.vartab-bvar.r
> +++ b/test/unittest/disasm/tst.vartab-bvar.r
> @@ -1,6 +1,5 @@
> NAME OFFSET KND SCP FLAG TYPE
> args arr glb r any (unknown) by ref (size 0)
> -uregs arr glb r D type (integer) (size 8)
> curthread scl glb r D type (pointer) (size 8)
> timestamp scl glb r D type (integer) (size 8)
> vtimestamp scl glb r D type (integer) (size 8)
> diff --git a/test/unittest/disasm/tst.vartab-bvar.sh b/test/unittest/disasm/tst.vartab-bvar.sh
> index b368f8bd..996cc332 100755
> --- a/test/unittest/disasm/tst.vartab-bvar.sh
> +++ b/test/unittest/disasm/tst.vartab-bvar.sh
> @@ -50,7 +50,7 @@ sdt:task::task_rename
> trace(timestamp);
> trace(ucaller);
> trace(uid);
> - trace(uregs[0]);
> + /* trace(uregs[0]); */ /* test this separately until uregs[0] works on all kernels */
> trace(ustackdepth);
> trace(vtimestamp);
> trace(walltimestamp);
> diff --git a/test/unittest/variables/bvar/tst.uregs.d b/test/unittest/variables/bvar/tst.uregs.d
> deleted file mode 100644
> index 5e0d507e..00000000
> --- a/test/unittest/variables/bvar/tst.uregs.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -/*
> - * Oracle Linux DTrace.
> - * Copyright (c) 2020, 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.
> - */
> -/* @@xfail: dtv2 */
> -
> -/*
> - * ASSERTION: The 'uregs' variable can be accessed and is not -1.
> - *
> - * SECTION: Variables/Built-in Variables/uregs
> - */
> -
> -#pragma D option quiet
> -
> -BEGIN {
> - trace(uregs);
> - exit(uregs != -1 ? 0 : 1);
> -}
> -
> -ERROR {
> - exit(1);
> -}
> --
> 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