Skip to content

Commit

Permalink
Correct storage size assignment for variables
Browse files Browse the repository at this point in the history
The implementation of global and local variables using BPF maps added
calls to dt_ident_set_storage() to set the offset and size of the data
storage for each variable.  It was setting the storage requirement for
any automatically declared variable to 8 bytes regardless of its type.
Since the datatype of such a variable is determined dynamically based
on its use, the storage assignment must be done once the datatype is
known.  But by then, some code was already generated based on the wrong
size.

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 18, 2021
1 parent 6437db5 commit 9a4c70e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
14 changes: 7 additions & 7 deletions libdtrace/dt_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1661,10 +1661,10 @@ dt_node_decl(void)
if (idp == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);

dt_ident_set_storage(idp, 8,
ctf_type_size(dtt.dtt_ctfp, type));

dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type);
dt_ident_set_storage(idp, 8,
ctf_type_size(dtt.dtt_ctfp,
dtt.dtt_type));

/*
* If we are declaring an associative array, use our
Expand Down Expand Up @@ -2754,10 +2754,6 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
if (idp == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);

/* aggregation storage size is set later, in dt_cg.c */
if (idkind != DT_IDENT_AGG)
dt_ident_set_storage(idp, 8, 8);

/*
* Arrays and aggregations are not cooked individually. They
* have dynamic types and must be referenced using operator [].
Expand Down Expand Up @@ -2871,6 +2867,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags)
xyerror(D_TYPE_ERR, "failed to lookup int64_t\n");

dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type);
dt_ident_set_storage(cp->dn_ident, 8,
ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type));
dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type);
}

Expand Down Expand Up @@ -3485,6 +3483,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
dt_ident_unref(lp->dn_ident)) {
dt_node_type_assign(lp, ctfp, type);
dt_ident_type_assign(lp->dn_ident, ctfp, type);
dt_ident_set_storage(lp->dn_ident, 8,
ctf_type_size(ctfp, type));

if (uref) {
lp->dn_flags |= DT_NF_USERLAND;
Expand Down
3 changes: 3 additions & 0 deletions test/unittest/variables/gvar/tst.undecl-offset.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NAME OFFSET KND SCP FLAG TYPE
a 0 scl glb r/w string (unknown) by ref (size 256)
b 100 scl glb w string (unknown) by ref (size 256)
51 changes: 51 additions & 0 deletions test/unittest/variables/gvar/tst.undecl-offset.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash
#
# Oracle Linux DTrace.
# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#

##
#
# ASSERTION: Storage size of undeclared variables is based on their discovered
# datatype
#
# SECTION: Variables/Scalar Variables
#
##

dtrace=$1

$dtrace $dt_flags -Sen '
BEGIN
{
a = "";
b = a;
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) {
$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 $?

0 comments on commit 9a4c70e

Please sign in to comment.