[DTrace-devel] [PATCH 15/20] Add support for string constants in compiled D programs
Kris Van Hees
kris.van.hees at oracle.com
Tue Jun 1 22:48:15 PDT 2021
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
include/dtrace/dif_defines.h | 2 +-
libdtrace/dt_cg.c | 76 +++++++++++++-----------
libdtrace/dt_dctx.h | 2 +
libdtrace/dt_printf.c | 2 +
test/unittest/codegen/tst.stack_layout.r | 22 +++----
test/unittest/scalars/tst.self.d | 1 -
test/unittest/sizeof/tst.SizeofString2.d | 1 -
7 files changed, 56 insertions(+), 50 deletions(-)
diff --git a/include/dtrace/dif_defines.h b/include/dtrace/dif_defines.h
index bca9c630..55087f4e 100644
--- a/include/dtrace/dif_defines.h
+++ b/include/dtrace/dif_defines.h
@@ -113,7 +113,7 @@
#endif
#define DIF_INTOFF_MAX 0xffff /* highest integer table offset */
-#define DIF_STROFF_MAX 0xffff /* highest string table offset */
+#define DIF_STROFF_MAX 0x7fff /* highest string table offset */
#define DIF_REGISTER_MAX 0xff /* highest register number */
#define DIF_VARIABLE_MAX 0xffff /* highest variable identifier */
#define DIF_SUBROUTINE_MAX 0xffff /* highest subroutine code */
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index c51e515c..e7cc00bc 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -21,6 +21,7 @@
#include <dt_printf.h>
#include <dt_provider.h>
#include <dt_probe.h>
+#include <dt_varint.h>
#include <bpf_asm.h>
static void dt_cg_node(dt_node_t *, dt_irlist_t *, dt_regset_t *);
@@ -160,19 +161,21 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
#define DT_CG_STORE_MAP_PTR(name, offset) \
do { \
dt_ident_t *idp = dt_dlib_get_map(dtp, name); \
- \
+ \
+ assert(idp != NULL); \
emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_FP, DCTX_FP(offset), 0)); \
- \
+ \
dt_cg_xsetx(dlp, idp, DT_LBL_NONE, BPF_REG_1, idp->di_id); \
emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_FP)); \
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DCTX_FP(offset))); \
emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_lookup_elem)); \
- \
+ \
emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_exit)); \
- \
+ \
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_FP, DCTX_FP(offset), BPF_REG_0)); \
} while(0)
+ DT_CG_STORE_MAP_PTR("strtab", DCTX_STRTAB);
if (dt_idhash_datasize(dtp->dt_aggs) > 0)
DT_CG_STORE_MAP_PTR("aggs", DCTX_AGG);
if (dt_idhash_datasize(dtp->dt_globals) > 0)
@@ -733,27 +736,16 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
dt_regset_free(drp, dnp->dn_reg);
return 0;
-#if 0
- } else if (dt_node_is_string(dnp->dn_args)) {
- size_t sz = dt_node_type_size(dnp->dn_args);
+ } else if (dt_node_is_string(dnp)) {
+ off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, kind,
+ size, 1, pfp, arg);
- /*
- * Strings are stored as a 64-bit size followed by a character
- * array. Given that all entries in the output buffer are
- * aligned at 64-bit boundaries, this guarantees that the
- * character array is also aligned at a 64-bit boundary.
- * We will pad the string to a multiple of 8 bytes as well.
- *
- * We store the size as two 32-bit values, lower 4 bytes first,
- * then the higher 4 bytes.
- */
- sz = P2ROUNDUP(sz, sizeof(uint64_t));
- emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, off, sz & ((1UL << 32)-1)));
- emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, off + 4, sz >> 32));
- dt_regset_free(drp, dnp->dn_args->dn_reg);
+ emit(dlp, BPF_MOV_REG(BPF_REG_0, BPF_REG_9));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, off));
+ dt_cg_memcpy(dlp, drp, BPF_REG_0, dnp->dn_reg, size);
+ dt_regset_free(drp, dnp->dn_reg);
- return sz + sizeof(uint64_t);
-#endif
+ return 0;
}
return -1;
@@ -1935,8 +1927,27 @@ dt_cg_store_var(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp,
/* store by value or by reference */
if (src->dn_flags & DT_NF_REF) {
+ size_t size;
+
emit(dlp, BPF_ALU64_IMM(BPF_ADD, reg, idp->di_offset));
- dt_cg_memcpy(dlp, drp, reg, src->dn_reg, idp->di_size);
+
+ /*
+ * Determine the amount of data to be copied. It is
+ * usually the size of the identifier, except for
+ * string constants where it is the size of the string
+ * constant (adjusted for the variable-width length
+ * prefix). An assignment of a string constant is a
+ * store of type 'string' with a RHS of type
+ * DT_TOK_STRING.
+ */
+ if (dt_node_is_string(src) &&
+ src->dn_right->dn_op == DT_TOK_STRING) {
+ size = dt_node_type_size(src->dn_right);
+ size += dt_vint_size(size) + 1;
+ } else
+ size = idp->di_size;
+
+ dt_cg_memcpy(dlp, drp, reg, src->dn_reg, size);
} else {
size_t size = idp->di_size;
@@ -3244,19 +3255,12 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
longjmp(yypcb->pcb_jmpbuf, EDT_STR2BIG);
/*
- * The string table will be loaded as value for the 0 element
- * in the strtab BPF array map. We use a function call to get
- * the actual string:
- * get_string(stroff);
+ * Calculate the address of the string data in the 'strtab' BPF
+ * map.
*/
- if (dt_regset_xalloc_args(drp) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
- idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_get_string");
- assert(idp != NULL);
- emit(dlp, BPF_MOV_IMM(BPF_REG_1, stroff));
- emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
- emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
- dt_regset_free_args(drp);
+ emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_FP, DT_STK_DCTX));
+ emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, dnp->dn_reg, DCTX_STRTAB));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, dnp->dn_reg, stroff));
break;
case DT_TOK_IDENT:
diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
index 0873602c..3ba474b0 100644
--- a/libdtrace/dt_dctx.h
+++ b/libdtrace/dt_dctx.h
@@ -38,6 +38,7 @@ typedef struct dt_dctx {
dt_activity_t *act; /* pointer to activity state */
dt_mstate_t *mst; /* DTrace machine state */
char *buf; /* Output buffer scratch memory */
+ char *strtab; /* String constant table */
char *agg; /* Aggregation data */
char *gvars; /* Global variables */
char *lvars; /* Local variables */
@@ -47,6 +48,7 @@ typedef struct dt_dctx {
#define DCTX_ACT offsetof(dt_dctx_t, act)
#define DCTX_MST offsetof(dt_dctx_t, mst)
#define DCTX_BUF offsetof(dt_dctx_t, buf)
+#define DCTX_STRTAB offsetof(dt_dctx_t, strtab)
#define DCTX_AGG offsetof(dt_dctx_t, agg)
#define DCTX_GVARS offsetof(dt_dctx_t, gvars)
#define DCTX_LVARS offsetof(dt_dctx_t, lvars)
diff --git a/libdtrace/dt_printf.c b/libdtrace/dt_printf.c
index 6d6187ee..cd2a8fce 100644
--- a/libdtrace/dt_printf.c
+++ b/libdtrace/dt_printf.c
@@ -16,6 +16,7 @@
#include <dt_printf.h>
#include <dt_string.h>
+#include <dt_varint.h>
#include <dt_impl.h>
/*ARGSUSED*/
@@ -489,6 +490,7 @@ pfprint_cstr(dtrace_hdl_t *dtp, FILE *fp, const char *format,
memcpy(s, addr, size);
s[size] = '\0';
+ s = (char *)dt_vint_skip(s);
return dt_printf(dtp, fp, format, s);
}
diff --git a/test/unittest/codegen/tst.stack_layout.r b/test/unittest/codegen/tst.stack_layout.r
index 48be58d2..cc23a6a1 100644
--- a/test/unittest/codegen/tst.stack_layout.r
+++ b/test/unittest/codegen/tst.stack_layout.r
@@ -1,12 +1,12 @@
Base: 0
-dctx: -56
-%r0: -64
-%r1: -72
-%r2: -80
-%r3: -88
-%r4: -96
-%r5: -104
-%r6: -112
-%r7: -120
-%r8: -128
-scratch: -129 .. -512
+dctx: -64
+%r0: -72
+%r1: -80
+%r2: -88
+%r3: -96
+%r4: -104
+%r5: -112
+%r6: -120
+%r7: -128
+%r8: -136
+scratch: -137 .. -512
diff --git a/test/unittest/scalars/tst.self.d b/test/unittest/scalars/tst.self.d
index 2611e993..515ee786 100644
--- a/test/unittest/scalars/tst.self.d
+++ b/test/unittest/scalars/tst.self.d
@@ -4,7 +4,6 @@
* 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/sizeof/tst.SizeofString2.d b/test/unittest/sizeof/tst.SizeofString2.d
index 62378a46..8abb9f91 100644
--- a/test/unittest/sizeof/tst.SizeofString2.d
+++ b/test/unittest/sizeof/tst.SizeofString2.d
@@ -4,7 +4,6 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/*
* ASSERTION: sizeof returns the size in bytes of any D expression or data
--
2.31.1
More information about the DTrace-devel
mailing list