[DTrace-devel] [PATCH v5] Add support for uregs[]

Kris Van Hees kris.van.hees at oracle.com
Mon Feb 27 00:55:00 UTC 2023


On Sun, Feb 26, 2023 at 07:45:40PM -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                             |  97 +++++++-
>  libdtrace/i386/regs.d                         |  20 +-
>  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   |  17 +-
>  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  |  17 +-
>  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 --
>  43 files changed, 585 insertions(+), 372 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 9f0675fa..ebd9a81c 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -3944,6 +3944,92 @@ dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
>  	TRACE_REGSET("    assoc_op: End  ");
>  }
>  
> +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;
> +
> +	/* check if out-of-bounds */
> +	if (idx >= sizeof(dt_pt_regs) / sizeof(uint64_t)) {
> +
> +#if defined(__amd64)
> +		/*
> +		 * Even if out-of-bounds, on x86 there are still a few
> +		 * indices that are used to access task->thread. members.
> +		 */
> +		if (idx <= 25) {
> +			ctf_file_t *cfp = dtp->dt_shared_ctf;
> +			ctf_id_t type;
> +			ctf_membinfo_t ctm;
> +			int offset, rc;
> +
> +			/* look up task->thread offset */
> +			if (!cfp)
> +				longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
> +
> +			type = ctf_lookup_by_name(cfp, "struct task_struct");
> +			if (type == CTF_ERR)
> +				longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
> +			if (ctf_member_info(cfp, type, "thread", &ctm) == CTF_ERR)
> +				longjmp(yypcb->pcb_jmpbuf, 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)
> +				longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
> +			switch (idx) {
> +			case 21: rc = ctf_member_info(cfp, type, "ds", &ctm); break;
> +			case 22: rc = ctf_member_info(cfp, type, "es", &ctm); break;
> +			case 23: rc = ctf_member_info(cfp, type, "fsbase", &ctm); break;
> +			case 24: rc = ctf_member_info(cfp, type, "gsbase", &ctm); break;
> +			case 25: rc = ctf_member_info(cfp, type, "trap_nr", &ctm); break;
> +			}
> +			if (rc == -1)
> +				longjmp(yypcb->pcb_jmpbuf, 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);
> +
> +			return;
> +		}
> +#endif
> +
> +		dnerror(dnp, D_UNKNOWN, "uregs[]: index out of bounds (%d)\n", idx);
> +
> +		return;
> +	}
> +
> +	/* if in-bounds, look up pt_regs[] */
> +	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[] is not supported on this kernel\n");

Can we move this to the beginning of the function, since really, if these
helpers do not exist, it is more consistent (as you mentioned before) to not
handle *any* indexing of uregs[].

> +
> +	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);
> +}
> +
>  /*
>   * Currently, this code is only used for the args[] and uregs[] arrays.
>   */
> @@ -4001,9 +4087,18 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
>  	dnp->dn_args->dn_value = saved;
>  	dnp->dn_reg = dnp->dn_args->dn_reg;
>  
> +	if (idp->di_id == DIF_VAR_UREGS) {
> +		/*
> +		 * We can use dnp->dn_args->dn_value, even though it was
> +		 * just overwritten by "saved", because we know the index
> +		 * is is a constant integer DT_NODE_INT.
> +		 */
> +		dt_cg_uregs(dnp->dn_args->dn_value, 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/libdtrace/i386/regs.d b/libdtrace/i386/regs.d
> index cbde4cea..12ce3ac9 100644
> --- a/libdtrace/i386/regs.d
> +++ b/libdtrace/i386/regs.d
> @@ -59,25 +59,25 @@ inline int R_R14 = 1;
>  inline int R_R15 = 0;
>  #pragma D binding "1.0" R_R15
>  
> -inline int R_EBX = R_GS + 1 + 0;
> +inline int R_EBX = R_RBX;
>  #pragma D binding "1.0" R_EBX
> -inline int R_ECX = R_GS + 1 + 1;
> +inline int R_ECX = R_RCX;
>  #pragma D binding "1.0" R_ECX
> -inline int R_EDX = R_GS + 1 + 2;
> +inline int R_EDX = R_RDX;
>  #pragma D binding "1.0" R_EDX
> -inline int R_ESI = R_GS + 1 + 3;
> +inline int R_ESI = R_RSI;
>  #pragma D binding "1.0" R_ESI
> -inline int R_EDI = R_GS + 1 + 4;
> +inline int R_EDI = R_RDI;
>  #pragma D binding "1.0" R_EDI
> -inline int R_EBP = R_GS + 1 + 5;
> +inline int R_EBP = R_RBP;
>  #pragma D binding "1.0" R_EBP
> -inline int R_EAX = R_GS + 1 + 6;
> +inline int R_EAX = R_RAX;
>  #pragma D binding "1.0" R_EAX
> -inline int R_EIP = R_GS + 1 + 12;
> +inline int R_EIP = R_RIP;
>  #pragma D binding "1.0" R_EIP
> -inline int R_EFL = R_GS + 1 + 14;
> +inline int R_EFL = R_RFL;
>  #pragma D binding "1.0" R_EFL
> -inline int R_ESP = R_GS + 1 + 15;
> +inline int R_ESP = R_RSP;
>  #pragma D binding "1.0" R_ESP
>  
>  inline int R_PC = R_EIP;
> 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..09024896
> --- /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[] is not supported on this kernel
> 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..0274240f
> --- /dev/null
> +++ b/test/unittest/arrays/err.D_UNKNOWN.uregs_badkernelversion.x
> @@ -0,0 +1,13 @@
> +#!/bin/bash
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
> +
> +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..00a7a8cc
> --- /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[]: index out of bounds (34)
> 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..02bfa4cf
> --- /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[]: index out of bounds (42)
> 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..4fb7f8c1
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-check.x
> @@ -0,0 +1,13 @@
> +#!/bin/bash
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
> +
> +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..f41cc672
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray-constants.x86_64.r
> @@ -0,0 +1,2 @@
> + 16 19 10 5 17 24 22 21 14 13 4 10 19 10 5 11 12 25 15 16 17 18 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..635c2a86 100755
> --- a/test/unittest/arrays/tst.uregsarray.arm64.x
> +++ b/test/unittest/arrays/tst.uregsarray.arm64.x
> @@ -1,4 +1,15 @@
> -#!/bin/sh
> +#!/bin/bash
>  
> -[ `uname -m` = "aarch64" ] && exit 0
> -exit 2
> +[ `uname -m` != "aarch64" ] && exit 2
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
> +
> +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..e63a58bd
> --- /dev/null
> +++ b/test/unittest/arrays/tst.uregsarray.x
> @@ -0,0 +1,13 @@
> +#!/bin/bash
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
> +
> +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..5441e564 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
> +#!/bin/bash
>  
> -[ `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 '.' ' '`
> +
> +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..4fb7f8c1
> --- /dev/null
> +++ b/test/unittest/disasm/tst.vartab-bvar-uregs0.x
> @@ -0,0 +1,13 @@
> +#!/bin/bash
> +
> +read MAJOR MINOR <<< `uname -r | grep -Eo '^[0-9]+\.[0-9]+' | tr '.' ' '`
> +
> +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