Skip to content

Commit

Permalink
Add support for built-in variable args
Browse files Browse the repository at this point in the history
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
  • Loading branch information
kvanhees committed Jun 7, 2022
1 parent 8cedded commit fb10fad
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 20 deletions.
57 changes: 41 additions & 16 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3619,23 +3619,27 @@ dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" assoc_op: End ");
}

/*
* Currently, this code is only used for the args[] and uregs[] arrays.
*/
static void
dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
dt_probe_t *prp = yypcb->pcb_probe;
uintmax_t saved = dnp->dn_args->dn_value;
dt_ident_t *idp = dnp->dn_ident;

ssize_t base;
size_t size;
int n;
dt_probe_t *prp = yypcb->pcb_probe;
uintmax_t saved = dnp->dn_args->dn_value;
dt_ident_t *idp = dnp->dn_ident;
dt_ident_t *fidp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_get_bvar");
size_t size;
int n;

assert(dnp->dn_kind == DT_NODE_VAR);
assert(!(idp->di_flags & DT_IDFLG_LOCAL));
assert(!(idp->di_flags & (DT_IDFLG_TLS | DT_IDFLG_LOCAL)));

assert(dnp->dn_args->dn_kind == DT_NODE_INT);
assert(dnp->dn_args->dn_list == NULL);

assert(fidp != NULL);

/*
* If this is a reference in the args[] array, temporarily modify the
* array index according to the static argument mapping (if any),
Expand All @@ -3653,18 +3657,39 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dnp->dn_args->dn_value = prp->mapping[saved];
}

/*
* Mark the identifier as referenced by the current DIFO. If it is an
* orphaned identifier, we also need to mark the primary identifier
* (global identifier with the same name).
*
* We can safely replace idp with the primary identifier at this point
* because they have the same id.
*/
idp->di_flags |= DT_IDFLG_DIFR;
if (idp->di_flags & DT_IDFLG_ORPHAN) {
idp = dt_idhash_lookup(yypcb->pcb_hdl->dt_globals, "args");
assert(idp != NULL);
idp->di_flags |= DT_IDFLG_DIFR;
}

dt_cg_node(dnp->dn_args, dlp, drp);
dnp->dn_args->dn_value = saved;

dnp->dn_reg = dnp->dn_args->dn_reg;

if (idp->di_flags & DT_IDFLG_TLS)
base = 0x2000;
else
base = 0x3000;
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);

idp->di_flags |= DT_IDFLG_DIFR;
emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_FP, base + dnp->dn_ident->di_id));
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));
dt_regset_xalloc(drp, BPF_REG_0);
emite(dlp, BPF_CALL_FUNC(fidp->di_id), fidp);
dt_regset_free_args(drp);

dt_cg_check_fault(yypcb);

emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
dt_regset_free(drp, BPF_REG_0);

/*
* If this is a reference to the args[] array, we need to take the
Expand All @@ -3687,7 +3712,7 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
n = sizeof(uint64_t) * NBBY - size * NBBY;

emit(dlp, BPF_ALU64_IMM(BPF_LSH, dnp->dn_reg, n));
emit(dlp, BPF_ALU64_REG((dnp->dn_flags & DT_NF_SIGNED) ? BPF_ARSH : BPF_RSH, dnp->dn_reg, n));
emit(dlp, BPF_ALU64_IMM((dnp->dn_flags & DT_NF_SIGNED) ? BPF_ARSH : BPF_RSH, dnp->dn_reg, n));
}

/*
Expand Down
5 changes: 5 additions & 0 deletions libdtrace/dt_ident.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,11 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
xyerror(D_ARGS_TYPE, "failed to resolve native type for "
"%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);

if (idp->di_type == CTF_ERR) {
idp->di_ctfp = DT_DYN_CTFP(dtp);
idp->di_type = DT_DYN_TYPE(dtp);
}

if (dtp->dt_xlatemode == DT_XL_STATIC && (
nnp == xnp || dt_node_is_argcompat(nnp, xnp))) {
dnp->dn_ident = dt_ident_create(idp->di_name, idp->di_kind,
Expand Down
35 changes: 35 additions & 0 deletions test/unittest/disasm/tst.ann-bvar.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
85 0 1 0000 ffffffff call dt_get_bvar ! arg0
85 0 1 0000 ffffffff call dt_get_bvar ! arg1
85 0 1 0000 ffffffff call dt_get_bvar ! arg2
85 0 1 0000 ffffffff call dt_get_bvar ! arg3
85 0 1 0000 ffffffff call dt_get_bvar ! arg4
85 0 1 0000 ffffffff call dt_get_bvar ! arg5
85 0 1 0000 ffffffff call dt_get_bvar ! arg6
85 0 1 0000 ffffffff call dt_get_bvar ! arg7
85 0 1 0000 ffffffff call dt_get_bvar ! arg8
85 0 1 0000 ffffffff call dt_get_bvar ! arg9
85 0 1 0000 ffffffff call dt_get_bvar ! args
85 0 1 0000 ffffffff call dt_get_bvar ! caller
85 0 1 0000 ffffffff call dt_get_bvar ! curcpu
85 0 1 0000 ffffffff call dt_get_bvar ! curthread
85 0 1 0000 ffffffff call dt_get_bvar ! epid
85 0 1 0000 ffffffff call dt_get_bvar ! errno
85 0 1 0000 ffffffff call dt_get_bvar ! execname
85 0 1 0000 ffffffff call dt_get_bvar ! gid
85 0 1 0000 ffffffff call dt_get_bvar ! id
85 0 1 0000 ffffffff call dt_get_bvar ! ipl
85 0 1 0000 ffffffff call dt_get_bvar ! pid
85 0 1 0000 ffffffff call dt_get_bvar ! ppid
85 0 1 0000 ffffffff call dt_get_bvar ! probefunc
85 0 1 0000 ffffffff call dt_get_bvar ! probemod
85 0 1 0000 ffffffff call dt_get_bvar ! probename
85 0 1 0000 ffffffff call dt_get_bvar ! probeprov
85 0 1 0000 ffffffff call dt_get_bvar ! stackdepth
85 0 1 0000 ffffffff call dt_get_bvar ! tid
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
53 changes: 53 additions & 0 deletions test/unittest/disasm/tst.ann-bvar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
#
# Oracle Linux DTrace.
# Copyright (c) 2022, 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

$dtrace $dt_flags -Sen '
sdt:task::task_rename
{
trace(arg0);
trace(arg1);
trace(arg2);
trace(arg3);
trace(arg4);
trace(arg5);
trace(arg6);
trace(arg7);
trace(arg8);
trace(arg9);
trace(args[0]);
trace(caller);
trace(curcpu);
trace(curthread);
trace(epid);
trace(errno);
trace(execname);
trace(gid);
trace(id);
trace(ipl);
trace(pid);
trace(ppid);
trace(probefunc);
trace(probemod);
trace(probename);
trace(probeprov);
trace(stackdepth);
trace(tid);
trace(timestamp);
trace(ucaller);
trace(uid);
trace(uregs[0]);
trace(ustackdepth);
trace(vtimestamp);
trace(walltimestamp);
exit(0);
}
' 2>&1 | awk '/ call dt_get_bvar/ { sub(/^[^:]+: /, ""); print; }'

exit $?
29 changes: 29 additions & 0 deletions test/unittest/variables/bvar/err.D_ARGS_IDX.args-neg-idx.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, 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: Accessing args[-1] for probes with arguments triggers a fault.
*
* SECTION: Variables/Built-in Variables/args
*/

#pragma D option quiet
#pragma D option destructive

BEGIN
{
system("echo write something > /dev/null");
}

write:entry {
trace(args[-1]);
exit(0);
}

ERROR {
exit(1);
}
23 changes: 23 additions & 0 deletions test/unittest/variables/bvar/err.D_ARGS_IDX.args-no-args.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, 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: Accessing args[0] for probes without arguments triggers a fault.
*
* SECTION: Variables/Built-in Variables/args
*/

#pragma D option quiet

BEGIN {
trace(args[0]);
exit(0);
}

ERROR {
exit(1);
}
32 changes: 32 additions & 0 deletions test/unittest/variables/bvar/err.D_ARGS_IDX.args-too-many.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, 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: Accessing args[i] for probes with n arguments fails when i >= n.
*
* SECTION: Variables/Built-in Variables/args
*/

#pragma D option quiet
#pragma D option destructive

BEGIN
{
system("echo write something > /dev/null");
}

write:entry {
trace(args[0]);
trace(args[1]);
trace(args[2]);
trace(args[3]);
exit(0);
}

ERROR {
exit(1);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 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 'args' variable can be accessed and is not -1.
* ASSERTION: The 'args' variable must be indexed.
*
* SECTION: Variables/Built-in Variables/args
*/
Expand All @@ -16,7 +15,7 @@

BEGIN {
trace(args);
exit(args != -1 ? 0 : 1);
exit(0);
}

ERROR {
Expand Down
23 changes: 23 additions & 0 deletions test/unittest/variables/bvar/err.D_PROTO_ARG.args-non-scalar-idx.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, 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: The index of args[] must be a scalar.
*
* SECTION: Variables/Built-in Variables/args
*/

BEGIN
{
trace(args["a"]);
exit(0);
}

ERROR
{
exit(1);
}
32 changes: 32 additions & 0 deletions test/unittest/variables/bvar/tst.args-match-argN.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, 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: When no argument mapping is in place, args[N] == argN, modulo
* datatype.
*
* SECTION: Variables/Built-in Variables/args
*/

#pragma D option quiet
#pragma D option destructive

BEGIN
{
system("echo write something > /dev/null");
}

write:entry {
printf("%x vs %x\n", args[0], arg0);
printf("%x vs %x\n", (uint64_t)args[1], arg1);
printf("%x vs %x\n", args[2], arg2);
exit(args[0] == arg0 && (uint64_t)args[1] == arg1 && args[2] == arg2 ? 0 : 1);
}

ERROR {
exit(1);
}

0 comments on commit fb10fad

Please sign in to comment.