Skip to content

Commit

Permalink
Add support for progenyof() subroutine
Browse files Browse the repository at this point in the history
Also, clean up err*progeny*.d tests.  In particular,

*)  err.D_FUNC_UNDEF.progenyofbad1.d was failing because it had always
    been wrong:  the test was mislabeled.  The test was introduced in patch
        c17a42e "Add the OpenSolaris dtrace testsuite."
    with a .r results file that explicitly indicates D_PROTO_LEN,
    even though the test name expects D_FUNC_UNDEF.  However, runtest.sh
    did not check the error tag.  Though runtest.sh was eventually fixed,
    the test fail was simply dismissed XFAIL.

*)  err.D_PROTO_LEN.progenyofbad2.d was passing, but for reasons unrelated
    to progenyof() or its argument checks.  The test used progenyof(trace())
    and therefore did not test progenyof() at all;  rather, it failed on
    trace(), which is missing its argument.

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>
  • Loading branch information
euloh authored and kvanhees committed Apr 22, 2022
1 parent ebfecdf commit 5149409
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 22 deletions.
1 change: 1 addition & 0 deletions bpf/Build
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bpf_dlib_SOURCES = \
get_dvar.c \
index.S \
lltostr.S \
progenyof.S \
probe_error.c \
rindex.S \
speculation.c \
Expand Down
88 changes: 88 additions & 0 deletions bpf/progenyof.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
*/

#define BPF_FUNC_probe_read 4
#define BPF_FUNC_get_current_task 35

.text
.align 4
.global dt_progenyof
.type dt_progenyof, @function
dt_progenyof:
#define ARG %r6
#define CNT %r7
#define PTR %r8
#define VAL %r9

/* uint64_t dt_progenyof(pid_t arg); */
mov ARG, %r1
lsh ARG, 32
rsh ARG, 32

/* assure the BPF verifier there is no infinite loop */
mov CNT, 256

/* ptr = bpf_get_current_task() */
call BPF_FUNC_get_current_task
mov PTR, %r0

.Lloop:
/* if (ptr == 0) goto Lret0 */
jeq PTR, 0, .Lret0

/* if (count <= 0) goto Lret0 */
jsle CNT, 0, .Lret0

/* val = *((uint32_t *)(ptr + TASK_PID)), using [%fp+-8] as temp */
mov %r1, %fp
add %r1, -8
mov %r2, 4
lddw %r3, TASK_PID
add %r3, PTR
call BPF_FUNC_probe_read
jne %r0, 0, .Lret0
ldxw VAL, [%fp+-8]
lsh VAL, 32
rsh VAL, 32

/* if (val == arg) goto Lret1 */
jeq VAL, ARG, .Lret1

/* val = *((uint64_t *)(ptr + TASK_REAL_PARENT)), using [%fp+-8] as temp */
mov %r1, %fp
add %r1, -8
mov %r2, 8
lddw %r3, TASK_REAL_PARENT
add %r3, PTR
call BPF_FUNC_probe_read
jne %r0, 0, .Lret0
ldxdw VAL, [%fp+-8]

/* if (val == ptr) goto Lret0 */
jeq VAL, PTR, .Lret0

/* ptr = val */
mov PTR, VAL

/* count-- */
sub CNT, 1

/* goto Lloop */
ja .Lloop

.Lret0:
/* return 0 */
mov %r0, 0
exit

.Lret1:
/* return 1 */
mov %r0, 1
exit
.size dt_progenyof, .-dt_progenyof
#undef ARG
#undef CNT
#undef PTR
#undef VAL
2 changes: 2 additions & 0 deletions libdtrace/dt_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ extern "C" {
#define DT_CONST_NCPUS 10
#define DT_CONST_PC 11
#define DT_CONST_TUPSZ 12
#define DT_CONST_TASK_REAL_PARENT 13
#define DT_CONST_TASK_PID 14

extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
int group_fd, unsigned long flags);
Expand Down
26 changes: 26 additions & 0 deletions libdtrace/dt_cc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,32 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
nrp->dofr_data = nrp->dofr_offset /
sizeof(struct bpf_insn);
continue;
case DT_CONST_TASK_REAL_PARENT: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
ctf_membinfo_t ctm;

if (type == CTF_ERR)
return -1;

if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
return -1;
nrp->dofr_data = ctm.ctm_offset / NBBY;
continue;
}
case DT_CONST_TASK_PID: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
ctf_membinfo_t ctm;

if (type == CTF_ERR)
return -1;

if (ctf_member_info(cfp, type, "pid", &ctm) == CTF_ERR)
return -1;
nrp->dofr_data = ctm.ctm_offset / NBBY;
continue;
}
default:
/* probe name -> value is probe id */
if (strchr(idp->di_name, ':') != NULL)
Expand Down
30 changes: 29 additions & 1 deletion libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3846,6 +3846,34 @@ dt_cg_subr_lltostr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-lltostr:End ");
}

static void
dt_cg_subr_progenyof(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
dt_ident_t *idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_progenyof");
dt_node_t *arg = dnp->dn_args;

assert(idp != NULL);

TRACE_REGSET(" subr-progenyof:Begin");
dt_cg_node(arg, dlp, drp);

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
emit(dlp, BPF_MOV_REG(BPF_REG_1, arg->dn_reg));
dt_regset_free(drp, arg->dn_reg);
dt_regset_xalloc(drp, BPF_REG_0);
emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
dt_regset_free_args(drp);

dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_reg == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
dt_regset_free(drp, BPF_REG_0);

TRACE_REGSET(" subr-progenyof:End ");
}

static void
dt_cg_subr_rand(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
Expand Down Expand Up @@ -4611,7 +4639,7 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
[DIF_SUBR_COPYIN] = NULL,
[DIF_SUBR_COPYINSTR] = NULL,
[DIF_SUBR_SPECULATION] = &dt_cg_subr_speculation,
[DIF_SUBR_PROGENYOF] = NULL,
[DIF_SUBR_PROGENYOF] = &dt_cg_subr_progenyof,
[DIF_SUBR_STRLEN] = &dt_cg_subr_strlen,
[DIF_SUBR_COPYOUT] = NULL,
[DIF_SUBR_COPYOUTSTR] = NULL,
Expand Down
2 changes: 2 additions & 0 deletions libdtrace/dt_dlibs.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL_ID(NCPUS, DT_IDENT_SCALAR, DT_CONST_NCPUS),
DT_BPF_SYMBOL_ID(PC, DT_IDENT_SCALAR, DT_CONST_PC),
DT_BPF_SYMBOL_ID(TUPSZ, DT_IDENT_SCALAR, DT_CONST_TUPSZ),
DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
DT_BPF_SYMBOL_ID(TASK_PID, DT_IDENT_SCALAR, DT_CONST_TASK_PID),

/* End-of-list marker */
{ NULL, }
Expand Down
2 changes: 0 additions & 2 deletions test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2007, 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.
*/

/*
* ASSERTION:
* progenyof() should return an error if the argument is an
* incorrect type.
* ASSERTION: progenyof() should take a pid_t argument.
*
* SECTION: Actions and Subroutines/progenyof()
*
*/


BEGIN
{
progenyof(trace());
progenyof("some_string");
exit(0);
}

4 changes: 4 additions & 0 deletions test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
prototype: pid_t
argument: string
18 changes: 18 additions & 0 deletions test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2007, 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: progenyof() should take a pid_t argument.
*
* SECTION: Actions and Subroutines/progenyof()
*/

BEGIN
{
progenyof(trace(1));
exit(0);
}
4 changes: 4 additions & 0 deletions test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
prototype: pid_t
argument: void
2 changes: 0 additions & 2 deletions test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r

This file was deleted.

18 changes: 18 additions & 0 deletions test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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: progenyof() should take one argument.
*
* SECTION: Actions and Subroutines/progenyof()
*/

BEGIN
{
progenyof();
exit(0);
}
2 changes: 2 additions & 0 deletions test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 0 args passed, 1 expected
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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:
* progenyof() should accept one argument - a pid
* ASSERTION: progenyof() should take one argument.
*
* SECTION: Actions and Subroutines/progenyof()
*
*/


BEGIN
{
progenyof(1, 2);
exit(0);
}

2 changes: 2 additions & 0 deletions test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- @@stderr --
dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 2 args passed, 1 expected
3 changes: 1 addition & 2 deletions test/unittest/funcs/tst.progenyof.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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.
*/
Expand All @@ -14,7 +14,6 @@
*
*/

/* @@xfail: dtv2 */
/* @@trigger: pid-tst-float */

#pragma D option quiet
Expand Down

0 comments on commit 5149409

Please sign in to comment.