[DTrace-devel] [PATCH 6/7] Add a disassembly listing mode 0 (-xdisasm=1) for code generation

eugene.loh at oracle.com eugene.loh at oracle.com
Thu Jun 24 18:42:46 PDT 2021


From: Eugene Loh <eugene.loh at oracle.com>

For debugging BPF instructions emitted during code generation, it
is useful to print debugging messages that are interwoven with
disassembled instructions.  Therefore, add disassembly support for
a listing mode 0 (-xdisasm=1) that disassembles instructions one
by one as they are produced by the code generator.

Developers can add more -xdisasm=1 diagnostic messages to the code
generator like this:

	if (DT_DISASM_CODEGEN_COND(pcb))
		fprintf(stderr, "hello world\n");

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_as.h           |  2 ++
 libdtrace/dt_cg.c           | 15 +++++++++++++++
 libdtrace/dt_dis.h          |  4 ++++
 libdtrace/dt_prov_dtrace.c  |  1 +
 libdtrace/dt_prov_pid.c     |  1 +
 libdtrace/dt_prov_profile.c |  1 +
 libdtrace/dt_prov_sdt.c     |  1 +
 libdtrace/dt_prov_syscall.c |  1 +
 8 files changed, 26 insertions(+)

diff --git a/libdtrace/dt_as.h b/libdtrace/dt_as.h
index e35bd7be..fff2fe7a 100644
--- a/libdtrace/dt_as.h
+++ b/libdtrace/dt_as.h
@@ -40,6 +40,8 @@ extern uint_t dt_irlist_label(dt_irlist_t *);
 #define emitle(dlp, lbl, instr, idp) \
 		({ \
 			dt_irnode_t *dip = dt_cg_node_alloc((lbl), (instr)); \
+			if (DT_DISASM_CODEGEN_COND(yypcb)) \
+				dt_dis_insn(dlp->dl_len, &(instr), stderr); \
 			dt_irlist_append((dlp), dip); \
 			if (idp != NULL) \
 				dip->di_extern = (idp); \
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 99e5c05a..90e20a51 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -1705,10 +1705,13 @@ void
 dt_cg_xsetx(dt_irlist_t *dlp, dt_ident_t *idp, uint_t lbl, int reg, uint64_t x)
 {
 	struct bpf_insn instr[2] = { BPF_LDDW(reg, x) };
+	uint_t cflags = yypcb->pcb_cflags;
 
 	emitle(dlp, lbl,
 		    instr[0], idp);
+	yypcb->pcb_cflags &= ~DTRACE_C_DIFV;	/* turn disassembly off */
 	emit(dlp,   instr[1]);
+	yypcb->pcb_cflags = cflags;		/* restore disassembly */
 }
 
 static void
@@ -4828,6 +4831,18 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
 		dnerror(dnp, D_CG_DYN, "expression cannot evaluate to result "
 			"of dynamic type\n");
 
+	if (DT_DISASM_CODEGEN_COND(pcb)) {
+		if (pcb->pcb_pdesc)
+			fprintf(stderr,
+			    "\nDisassembly (#0) code generation %s:%s:%s:%s:\n",
+			    pcb->pcb_pdesc->prv ? pcb->pcb_pdesc->prv : "",
+			    pcb->pcb_pdesc->mod ? pcb->pcb_pdesc->mod : "",
+			    pcb->pcb_pdesc->fun ? pcb->pcb_pdesc->fun : "",
+			    pcb->pcb_pdesc->prb ? pcb->pcb_pdesc->prb : "");
+		else
+			fprintf(stderr, "\nDisassembly (#0) code generation:\n");
+	}
+
 	/*
 	 * If we're generating code for a translator body, assign the input
 	 * parameter to the first available register (i.e. caller passes %r1).
diff --git a/libdtrace/dt_dis.h b/libdtrace/dt_dis.h
index 1d3ba7ac..a5224851 100644
--- a/libdtrace/dt_dis.h
+++ b/libdtrace/dt_dis.h
@@ -23,6 +23,7 @@ extern "C" {
  * The values can be combined to select multiple listings.  The '-S' option
  * must also be supplied in order for disassembler output to be generated.
  */
+#define DT_DISASM_OPT_CODEGEN		1
 #define DT_DISASM_OPT_CLAUSE		2
 #define DT_DISASM_OPT_PROG		4
 #define DT_DISASM_OPT_PROG_LINKED	8
@@ -31,6 +32,9 @@ extern "C" {
 /*
  * Macros to make a call to the disassembler for specific disassembler listings.
  */
+#define DT_DISASM_CODEGEN_COND(pcb) \
+	((pcb)->pcb_cflags & DTRACE_C_DIFV && \
+	    (pcb)->pcb_hdl->dt_disasm & DT_DISASM_OPT_CODEGEN)
 #define DT_DISASM_CLAUSE(dtp, cflags, pp, fp) \
 	do { \
 		if (((cflags) & DTRACE_C_DIFV) && \
diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
index 1c40c233..961af503 100644
--- a/libdtrace/dt_prov_dtrace.c
+++ b/libdtrace/dt_prov_dtrace.c
@@ -14,6 +14,7 @@
 
 #include "dt_dctx.h"
 #include "dt_cg.h"
+#include "dt_dis.h"
 #include "dt_provider.h"
 #include "dt_probe.h"
 
diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
index 2e9c5bee..20559284 100644
--- a/libdtrace/dt_prov_pid.c
+++ b/libdtrace/dt_prov_pid.c
@@ -14,6 +14,7 @@
 
 #include "dt_dctx.h"
 #include "dt_cg.h"
+#include "dt_dis.h"
 #include "dt_list.h"
 #include "dt_provider.h"
 #include "dt_probe.h"
diff --git a/libdtrace/dt_prov_profile.c b/libdtrace/dt_prov_profile.c
index 313c8c9c..7dc9a31d 100644
--- a/libdtrace/dt_prov_profile.c
+++ b/libdtrace/dt_prov_profile.c
@@ -14,6 +14,7 @@
 #include "dt_dctx.h"
 #include "dt_cg.h"
 #include "dt_bpf.h"
+#include "dt_dis.h"
 #include "dt_probe.h"
 
 static const char		prvname[] = "profile";
diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
index 320edbd2..ad604123 100644
--- a/libdtrace/dt_prov_sdt.c
+++ b/libdtrace/dt_prov_sdt.c
@@ -30,6 +30,7 @@
 #include "dt_dctx.h"
 #include "dt_cg.h"
 #include "dt_bpf.h"
+#include "dt_dis.h"
 #include "dt_provider.h"
 #include "dt_probe.h"
 #include "dt_pt_regs.h"
diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
index bbf45888..7ad256dc 100644
--- a/libdtrace/dt_prov_syscall.c
+++ b/libdtrace/dt_prov_syscall.c
@@ -31,6 +31,7 @@
 
 #include "dt_dctx.h"
 #include "dt_cg.h"
+#include "dt_dis.h"
 #include "dt_provider.h"
 #include "dt_probe.h"
 #include "dt_pt_regs.h"
-- 
2.18.4




More information about the DTrace-devel mailing list