summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>2008-04-26 05:09:19 +0000
committerjb <jb@FreeBSD.org>2008-04-26 05:09:19 +0000
commit3719d4861d302aeba3327d201373775328f855ab (patch)
tree998e65b18f1c641b2c992775fb390d3f07eef511 /cddl
parent7bc32bb24c69d0256d0170c86445386fd5ae152d (diff)
downloadFreeBSD-src-3719d4861d302aeba3327d201373775328f855ab.zip
FreeBSD-src-3719d4861d302aeba3327d201373775328f855ab.tar.gz
* Handle the different ioctl design.
* Add a couple of FreeBSD action extensions.
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c102
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c54
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c382
3 files changed, 524 insertions, 14 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index 64b2922..8bd0915 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -87,6 +87,7 @@
#include <sys/wait.h>
#include <assert.h>
+#include <string.h>
#include <strings.h>
#include <signal.h>
#include <unistd.h>
@@ -948,6 +949,77 @@ dt_action_speculate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
}
static void
+dt_action_printm(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_node_t *size = dnp->dn_args;
+ dt_node_t *addr = dnp->dn_args->dn_list;
+
+ char n[DT_TYPE_NAMELEN];
+
+ if (dt_node_is_posconst(size) == 0) {
+ dnerror(size, D_PRINTM_SIZE, "printm( ) argument #1 must "
+ "be a non-zero positive integral constant expression\n");
+ }
+
+ if (dt_node_is_pointer(addr) == 0) {
+ dnerror(addr, D_PRINTM_ADDR,
+ "printm( ) argument #2 is incompatible with "
+ "prototype:\n\tprototype: pointer\n"
+ "\t argument: %s\n",
+ dt_node_type_name(addr, n, sizeof (n)));
+ }
+
+ dt_cg(yypcb, addr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_PRINTM;
+
+ ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value + sizeof(uintptr_t);
+}
+
+static void
+dt_action_printt(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
+{
+ dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
+
+ dt_node_t *size = dnp->dn_args;
+ dt_node_t *addr = dnp->dn_args->dn_list;
+
+ char n[DT_TYPE_NAMELEN];
+
+ if (dt_node_is_posconst(size) == 0) {
+ dnerror(size, D_PRINTT_SIZE, "printt( ) argument #1 must "
+ "be a non-zero positive integral constant expression\n");
+ }
+
+ if (addr == NULL || addr->dn_kind != DT_NODE_FUNC ||
+ addr->dn_ident != dt_idhash_lookup(dtp->dt_globals, "typeref")) {
+ dnerror(addr, D_PRINTT_ADDR,
+ "printt( ) argument #2 is incompatible with "
+ "prototype:\n\tprototype: typeref()\n"
+ "\t argument: %s\n",
+ dt_node_type_name(addr, n, sizeof (n)));
+ }
+
+ dt_cg(yypcb, addr);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_kind = DTRACEACT_PRINTT;
+
+ ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
+
+ /*
+ * Allow additional buffer space for the data size, type size,
+ * type string length and a stab in the dark (32 bytes) for the
+ * type string. The type string is part of the typeref() that
+ * this action references.
+ */
+ ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value + 3 * sizeof(uintptr_t) + 32;
+
+}
+
+static void
dt_action_commit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
{
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
@@ -1013,6 +1085,12 @@ dt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
case DT_ACT_PRINTF:
dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_PRINTF);
break;
+ case DT_ACT_PRINTM:
+ dt_action_printm(dtp, dnp->dn_expr, sdp);
+ break;
+ case DT_ACT_PRINTT:
+ dt_action_printt(dtp, dnp->dn_expr, sdp);
+ break;
case DT_ACT_RAISE:
dt_action_raise(dtp, dnp->dn_expr, sdp);
break;
@@ -1589,7 +1667,9 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
char **argv = malloc(sizeof (char *) * (argc + 5));
FILE *ofp = tmpfile();
+#if defined(sun)
char ipath[20], opath[20]; /* big enough for /dev/fd/ + INT_MAX + \0 */
+#endif
char verdef[32]; /* big enough for -D__SUNW_D_VERSION=0x%08x + \0 */
struct sigaction act, oact;
@@ -1597,7 +1677,11 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
int wstat, estat;
pid_t pid;
+#if defined(sun)
off64_t off;
+#else
+ off_t off = 0;
+#endif
int c;
if (argv == NULL || ofp == NULL) {
@@ -1624,8 +1708,10 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
(void) fseeko64(ifp, off, SEEK_SET);
}
+#if defined(sun)
(void) snprintf(ipath, sizeof (ipath), "/dev/fd/%d", fileno(ifp));
(void) snprintf(opath, sizeof (opath), "/dev/fd/%d", fileno(ofp));
+#endif
bcopy(dtp->dt_cpp_argv, argv, sizeof (char *) * argc);
@@ -1633,6 +1719,7 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
"-D__SUNW_D_VERSION=0x%08x", dtp->dt_vmax);
argv[argc++] = verdef;
+#if defined(sun)
switch (dtp->dt_stdcmode) {
case DT_STDC_XA:
case DT_STDC_XT:
@@ -1645,6 +1732,9 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
argv[argc++] = ipath;
argv[argc++] = opath;
+#else
+ argv[argc++] = "-P";
+#endif
argv[argc] = NULL;
/*
@@ -1671,6 +1761,12 @@ dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
}
if (pid == 0) {
+#if !defined(sun)
+ if (isatty(fileno(ifp)) == 0)
+ lseek(fileno(ifp), off, SEEK_SET);
+ dup2(fileno(ifp), 0);
+ dup2(fileno(ofp), 1);
+#endif
(void) execvp(dtp->dt_cpp_path, argv);
_exit(errno == ENOENT ? 127 : 126);
}
@@ -2010,8 +2106,10 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
dt_dprintf("skipping library %s: %s\n",
dld->dtld_library,
dtrace_errmsg(dtp, dtrace_errno(dtp)));
- } else
+ } else {
+ dld->dtld_loaded = B_TRUE;
dt_program_destroy(dtp, pgp);
+ }
}
dt_lib_depend_free(dtp);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
index 4557c6f..a33cccd 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
@@ -267,7 +267,7 @@ dt_cg_field_get(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
* properties are used to compute shift as USHIFT or SSHIFT, below.
*/
if (dnp->dn_flags & DT_NF_SIGNED) {
-#ifdef _BIG_ENDIAN
+#if BYTE_ORDER == _BIG_ENDIAN
shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
mp->ctm_offset % NBBY;
#else
@@ -281,7 +281,7 @@ dt_cg_field_get(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
instr = DIF_INSTR_FMT(DIF_OP_SRA, r1, r2, r1);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
} else {
-#ifdef _BIG_ENDIAN
+#if BYTE_ORDER == _BIG_ENDIAN
shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
(mp->ctm_offset % NBBY + e.cte_bits);
#else
@@ -369,7 +369,7 @@ dt_cg_field_set(dt_node_t *src, dt_irlist_t *dlp,
* input register to width cte_bits, and cmask as the mask used to
* pass through the containing bits and zero the field bits.
*/
-#ifdef _BIG_ENDIAN
+#if BYTE_ORDER == _BIG_ENDIAN
shift = clp2(P2ROUNDUP(e.cte_bits, NBBY) / NBBY) * NBBY -
(m.ctm_offset % NBBY + e.cte_bits);
#else
@@ -1339,6 +1339,40 @@ dt_cg_inline(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
static void
+dt_cg_func_typeref(dtrace_hdl_t *dtp, dt_node_t *dnp)
+{
+ dtrace_typeinfo_t dtt;
+ dt_node_t *addr = dnp->dn_args;
+ dt_node_t *nelm = addr->dn_list;
+ dt_node_t *strp = nelm->dn_list;
+ dt_node_t *typs = strp->dn_list;
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+
+ ctf_type_name(addr->dn_ctfp, addr->dn_type, buf, sizeof (buf));
+
+ /*
+ * XXX Hack alert! XXX
+ * The prototype has two dummy args that we munge to represent
+ * the type string and the type size.
+ *
+ * Yes, I hear your grumble, but it works for now. We'll come
+ * up with a more elegant implementation later. :-)
+ */
+ free(strp->dn_string);
+
+ if ((p = strchr(buf, '*')) != NULL)
+ *p = '\0';
+
+ strp->dn_string = strdup(buf);
+
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY, buf, &dtt) < 0)
+ return;
+
+ typs->dn_value = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
+}
+
+static void
dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
ctf_file_t *ctfp = dnp->dn_ctfp;
@@ -1793,7 +1827,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
switch (dnp->dn_kind) {
- case DT_NODE_FUNC:
+ case DT_NODE_FUNC: {
+ dtrace_hdl_t *dtp = yypcb->pcb_hdl;
+
if ((idp = dnp->dn_ident)->di_kind != DT_IDENT_FUNC) {
dnerror(dnp, D_CG_EXPR, "%s %s( ) may not be "
"called from a D expression (D program "
@@ -1801,6 +1837,15 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_idkind_name(idp->di_kind), idp->di_name);
}
+ switch (idp->di_id) {
+ case DIF_SUBR_TYPEREF:
+ dt_cg_func_typeref(dtp, dnp);
+ break;
+
+ default:
+ break;
+ }
+
dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
@@ -1813,6 +1858,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_node_alloc(DT_LBL_NONE, instr));
break;
+ }
case DT_NODE_VAR:
if (dnp->dn_ident->di_kind == DT_IDENT_XLSOU ||
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
index 62d39e0..776fd17 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -32,7 +32,9 @@
#include <limits.h>
#include <assert.h>
#include <ctype.h>
+#if defined(sun)
#include <alloca.h>
+#endif
#include <dt_impl.h>
#define DT_MASK_LO 0x00000000FFFFFFFFULL
@@ -710,7 +712,7 @@ dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
/*ARGSUSED*/
int
dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
- size_t nbytes, int width, int quiet)
+ size_t nbytes, int width, int quiet, int raw)
{
/*
* If the byte stream is a series of printable characters, followed by
@@ -723,7 +725,7 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
if (nbytes == 0)
return (0);
- if (dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
+ if (raw || dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
goto raw;
for (i = 0; i < nbytes; i++) {
@@ -858,7 +860,7 @@ dt_print_stack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
return (dt_set_errno(dtp, EDT_BADSTACKPC));
}
- if (pc == NULL)
+ if (pc == 0)
break;
addr += size;
@@ -946,15 +948,23 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
if (P != NULL)
dt_proc_lock(dtp, P); /* lock handle while we perform lookups */
- for (i = 0; i < depth && pc[i] != NULL; i++) {
+ for (i = 0; i < depth && pc[i] != 0; i++) {
const prmap_t *map;
if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0)
break;
+#if defined(sun)
if (P != NULL && Plookup_by_addr(P, pc[i],
+#else
+ if (P != NULL && proc_addr2sym(P, pc[i],
+#endif
name, sizeof (name), &sym) == 0) {
+#if defined(sun)
(void) Pobjname(P, pc[i], objname, sizeof (objname));
+#else
+ (void) proc_objname(P, pc[i], objname, sizeof (objname));
+#endif
if (pc[i] > sym.st_value) {
(void) snprintf(c, sizeof (c),
@@ -965,8 +975,12 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
"%s`%s", dt_basename(objname), name);
}
} else if (str != NULL && str[0] != '\0' && str[0] != '@' &&
+#if defined(sun)
(P != NULL && ((map = Paddr_to_map(P, pc[i])) == NULL ||
(map->pr_mflags & MA_WRITE)))) {
+#else
+ (P != NULL && ((map = proc_addr2map(P, pc[i])) == NULL))) {
+#endif
/*
* If the current string pointer in the string table
* does not point to an empty string _and_ the program
@@ -982,8 +996,12 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
*/
(void) snprintf(c, sizeof (c), "%s", str);
} else {
+#if defined(sun)
if (P != NULL && Pobjname(P, pc[i], objname,
- sizeof (objname)) != NULL) {
+#else
+ if (P != NULL && proc_objname(P, pc[i], objname,
+#endif
+ sizeof (objname)) != 0) {
(void) snprintf(c, sizeof (c), "%s`0x%llx",
dt_basename(objname), (u_longlong_t)pc[i]);
} else {
@@ -1052,7 +1070,11 @@ dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act)
dt_proc_lock(dtp, P);
+#if defined(sun)
if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0)
+#else
+ if (proc_addr2sym(P, pc, NULL, 0, &sym) == 0)
+#endif
pc = sym.st_value;
dt_proc_unlock(dtp, P);
@@ -1095,7 +1117,11 @@ dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
if (P != NULL)
dt_proc_lock(dtp, P); /* lock handle while we perform lookups */
- if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != NULL) {
+#if defined(sun)
+ if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != 0) {
+#else
+ if (P != NULL && proc_objname(P, pc, objname, sizeof (objname)) != 0) {
+#endif
(void) snprintf(c, sizeof (c), "%s", dt_basename(objname));
} else {
(void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc);
@@ -1111,6 +1137,314 @@ dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
return (err);
}
+int
+dt_print_memory(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr)
+{
+ int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+ size_t nbytes = *((uintptr_t *) addr);
+
+ return (dt_print_bytes(dtp, fp, addr + sizeof(uintptr_t),
+ nbytes, 50, quiet, 1));
+}
+
+typedef struct dt_type_cbdata {
+ dtrace_hdl_t *dtp;
+ dtrace_typeinfo_t dtt;
+ caddr_t addr;
+ caddr_t addrend;
+ const char *name;
+ int f_type;
+ int indent;
+ int type_width;
+ int name_width;
+ FILE *fp;
+} dt_type_cbdata_t;
+
+static int dt_print_type_data(dt_type_cbdata_t *, ctf_id_t);
+
+static int
+dt_print_type_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ dt_type_cbdata_t cbdata;
+ dt_type_cbdata_t *cbdatap = arg;
+ ssize_t ssz;
+
+ if ((ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type)) <= 0)
+ return (0);
+
+ off /= 8;
+
+ cbdata = *cbdatap;
+ cbdata.name = name;
+ cbdata.addr += off;
+ cbdata.addrend = cbdata.addr + ssz;
+
+ return (dt_print_type_data(&cbdata, type));
+}
+
+static int
+dt_print_type_width(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+ dt_type_cbdata_t *cbdatap = arg;
+ size_t sz = strlen(name);
+
+ ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+ if ((p = strchr(buf, '[')) != NULL)
+ p[-1] = '\0';
+ else
+ p = "";
+
+ sz += strlen(p);
+
+ if (sz > cbdatap->name_width)
+ cbdatap->name_width = sz;
+
+ sz = strlen(buf);
+
+ if (sz > cbdatap->type_width)
+ cbdatap->type_width = sz;
+
+ return (0);
+}
+
+static int
+dt_print_type_data(dt_type_cbdata_t *cbdatap, ctf_id_t type)
+{
+ caddr_t addr = cbdatap->addr;
+ caddr_t addrend = cbdatap->addrend;
+ char buf[DT_TYPE_NAMELEN];
+ char *p;
+ int cnt = 0;
+ uint_t kind = ctf_type_kind(cbdatap->dtt.dtt_ctfp, type);
+ ssize_t ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type);
+
+ ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+ if ((p = strchr(buf, '[')) != NULL)
+ p[-1] = '\0';
+ else
+ p = "";
+
+ if (cbdatap->f_type) {
+ int type_width = roundup(cbdatap->type_width + 1, 4);
+ int name_width = roundup(cbdatap->name_width + 1, 4);
+
+ name_width -= strlen(cbdatap->name);
+
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s%-*s%s%-*s = ",cbdatap->indent * 4,"",type_width,buf,cbdatap->name,name_width,p);
+ }
+
+ while (addr < addrend) {
+ dt_type_cbdata_t cbdata;
+ ctf_arinfo_t arinfo;
+ ctf_encoding_t cte;
+ uintptr_t *up;
+ void *vp = addr;
+ cbdata = *cbdatap;
+ cbdata.name = "";
+ cbdata.addr = addr;
+ cbdata.addrend = addr + ssz;
+ cbdata.f_type = 0;
+ cbdata.indent++;
+ cbdata.type_width = 0;
+ cbdata.name_width = 0;
+
+ if (cnt > 0)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s", cbdatap->indent * 4,"");
+
+ switch (kind) {
+ case CTF_K_INTEGER:
+ if (ctf_type_encoding(cbdatap->dtt.dtt_ctfp, type, &cte) != 0)
+ return (-1);
+ if ((cte.cte_format & CTF_INT_SIGNED) != 0)
+ switch (cte.cte_bits) {
+ case 8:
+ if (isprint(*((char *) vp)))
+ dt_printf(cbdatap->dtp, cbdatap->fp, "'%c', ", *((char *) vp));
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((char *) vp), *((char *) vp));
+ break;
+ case 16:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%hd (0x%hx);\n", *((short *) vp), *((u_short *) vp));
+ break;
+ case 32:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((int *) vp), *((u_int *) vp));
+ break;
+ case 64:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%jd (0x%jx);\n", *((long long *) vp), *((unsigned long long *) vp));
+ break;
+ default:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ }
+ else
+ switch (cte.cte_bits) {
+ case 8:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((uint8_t *) vp) & 0xff, *((uint8_t *) vp) & 0xff);
+ break;
+ case 16:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%hu (0x%hx);\n", *((u_short *) vp), *((u_short *) vp));
+ break;
+ case 32:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((u_int *) vp), *((u_int *) vp));
+ break;
+ case 64:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%ju (0x%jx);\n", *((unsigned long long *) vp), *((unsigned long long *) vp));
+ break;
+ default:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ }
+ break;
+ case CTF_K_FLOAT:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FLOAT: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+ break;
+ case CTF_K_POINTER:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%p;\n", *((void **) addr));
+ break;
+ case CTF_K_ARRAY:
+ if (ctf_array_info(cbdatap->dtt.dtt_ctfp, type, &arinfo) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n%*s",cbdata.indent * 4,"");
+ dt_print_type_data(&cbdata, arinfo.ctr_contents);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_FUNCTION:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FUNCTION:\n");
+ break;
+ case CTF_K_STRUCT:
+ cbdata.f_type = 1;
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_width, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_member, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_UNION:
+ cbdata.f_type = 1;
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_width, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+ if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+ dt_print_type_member, &cbdata) != 0)
+ return (-1);
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+ break;
+ case CTF_K_ENUM:
+ dt_printf(cbdatap->dtp, cbdatap->fp, "%s;\n", ctf_enum_name(cbdatap->dtt.dtt_ctfp, type, *((int *) vp)));
+ break;
+ case CTF_K_TYPEDEF:
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_VOLATILE:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "volatile ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_CONST:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "const ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ case CTF_K_RESTRICT:
+ if (cbdatap->f_type)
+ dt_printf(cbdatap->dtp, cbdatap->fp, "restrict ");
+ dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+ break;
+ default:
+ break;
+ }
+
+ addr += ssz;
+ cnt++;
+ }
+
+ return (0);
+}
+
+static int
+dt_print_type(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr)
+{
+ caddr_t addrend;
+ char *p;
+ dtrace_typeinfo_t dtt;
+ dt_type_cbdata_t cbdata;
+ int num = 0;
+ int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+ ssize_t ssz;
+
+ if (!quiet)
+ dt_printf(dtp, fp, "\n");
+
+ /* Get the total number of bytes of data buffered. */
+ size_t nbytes = *((uintptr_t *) addr);
+ addr += sizeof(uintptr_t);
+
+ /*
+ * Get the size of the type so that we can check that it matches
+ * the CTF data we look up and so that we can figure out how many
+ * type elements are buffered.
+ */
+ size_t typs = *((uintptr_t *) addr);
+ addr += sizeof(uintptr_t);
+
+ /*
+ * Point to the type string in the buffer. Get it's string
+ * length and round it up to become the offset to the start
+ * of the buffered type data which we would like to be aligned
+ * for easy access.
+ */
+ char *strp = (char *) addr;
+ int offset = roundup(strlen(strp) + 1, sizeof(uintptr_t));
+
+ /*
+ * The type string might have a format such as 'int [20]'.
+ * Check if there is an array dimension present.
+ */
+ if ((p = strchr(strp, '[')) != NULL) {
+ /* Strip off the array dimension. */
+ *p++ = '\0';
+
+ for (; *p != '\0' && *p != ']'; p++)
+ num = num * 10 + *p - '0';
+ } else
+ /* No array dimension, so default. */
+ num = 1;
+
+ /* Lookup the CTF type from the type string. */
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY, strp, &dtt) < 0)
+ return (-1);
+
+ /* Offset the buffer address to the start of the data... */
+ addr += offset;
+
+ ssz = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
+
+ if (typs != ssz) {
+ printf("Expected type size from buffer (%lu) to match type size looked up now (%ld)\n", (u_long) typs, (long) ssz);
+ return (-1);
+ }
+
+ cbdata.dtp = dtp;
+ cbdata.dtt = dtt;
+ cbdata.name = "";
+ cbdata.addr = addr;
+ cbdata.addrend = addr + nbytes;
+ cbdata.indent = 1;
+ cbdata.f_type = 1;
+ cbdata.type_width = 0;
+ cbdata.name_width = 0;
+ cbdata.fp = fp;
+
+ return (dt_print_type_data(&cbdata, dtt.dtt_type));
+}
+
static int
dt_print_sym(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr)
{
@@ -1430,7 +1764,7 @@ dt_print_datum(dtrace_hdl_t *dtp, FILE *fp, dtrace_recdesc_t *rec,
(uint32_t)normal);
break;
default:
- err = dt_print_bytes(dtp, fp, addr, size, 50, 0);
+ err = dt_print_bytes(dtp, fp, addr, size, 50, 0, 0);
break;
}
@@ -1805,6 +2139,18 @@ again:
goto nextrec;
}
+ if (act == DTRACEACT_PRINTM) {
+ if (dt_print_memory(dtp, fp, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
+ if (act == DTRACEACT_PRINTT) {
+ if (dt_print_type(dtp, fp, addr) < 0)
+ return (-1);
+ goto nextrec;
+ }
+
if (DTRACEACT_ISPRINTFLIKE(act)) {
void *fmtdata;
int (*func)(dtrace_hdl_t *, FILE *, void *,
@@ -1935,7 +2281,7 @@ nofmt:
break;
default:
n = dt_print_bytes(dtp, fp, addr,
- rec->dtrd_size, 33, quiet);
+ rec->dtrd_size, 33, quiet, 0);
break;
}
@@ -2064,13 +2410,20 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
dt_begin_t begin;
processorid_t cpu = dtp->dt_beganon;
dtrace_bufdesc_t nbuf;
+#if !defined(sun)
+ dtrace_bufdesc_t *pbuf;
+#endif
int rval, i;
static int max_ncpus;
dtrace_optval_t size;
dtp->dt_beganon = -1;
+#if defined(sun)
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
/*
* We really don't expect this to fail, but it is at least
* technically possible for this to fail with ENOENT. In this
@@ -2132,7 +2485,12 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
if (i == cpu)
continue;
+#if defined(sun)
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &nbuf) == -1) {
+#else
+ pbuf = &nbuf;
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &pbuf) == -1) {
+#endif
/*
* If we failed with ENOENT, it may be because the
* CPU was unconfigured -- this is okay. Any other
@@ -2239,7 +2597,11 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
if (dtp->dt_stopped && (i == dtp->dt_endedon))
continue;
+#if defined(sun)
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
/*
* If we failed with ENOENT, it may be because the
* CPU was unconfigured -- this is okay. Any other
@@ -2260,7 +2622,11 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
buf->dtbd_cpu = dtp->dt_endedon;
+#if defined(sun)
if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, buf) == -1) {
+#else
+ if (dt_ioctl(dtp, DTRACEIOC_BUFSNAP, &buf) == -1) {
+#endif
/*
* This _really_ shouldn't fail, but it is strictly speaking
* possible for this to return ENOENT if the CPU that called
OpenPOWER on IntegriCloud