summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdtrace/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdtrace/common')
-rw-r--r--usr/src/lib/libdtrace/common/dt_cg.c50
-rw-r--r--usr/src/lib/libdtrace/common/dt_decl.c4
-rw-r--r--usr/src/lib/libdtrace/common/dt_dis.c20
-rw-r--r--usr/src/lib/libdtrace/common/dt_impl.h1
-rw-r--r--usr/src/lib/libdtrace/common/dt_link.c18
-rw-r--r--usr/src/lib/libdtrace/common/dt_module.c92
-rw-r--r--usr/src/lib/libdtrace/common/dt_open.c45
-rw-r--r--usr/src/lib/libdtrace/common/dt_options.c73
-rw-r--r--usr/src/lib/libdtrace/common/dt_parser.c4
-rw-r--r--usr/src/lib/libdtrace/common/dt_program.c9
-rw-r--r--usr/src/lib/libdtrace/common/dt_work.c32
-rw-r--r--usr/src/lib/libdtrace/common/dtrace.h1
-rw-r--r--usr/src/lib/libdtrace/common/mac.d.in66
-rw-r--r--usr/src/lib/libdtrace/common/mac.sed.in45
-rw-r--r--usr/src/lib/libdtrace/common/vnd.d28
15 files changed, 419 insertions, 69 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_cg.c b/usr/src/lib/libdtrace/common/dt_cg.c
index 28db9b2262..9f3625e6ee 100644
--- a/usr/src/lib/libdtrace/common/dt_cg.c
+++ b/usr/src/lib/libdtrace/common/dt_cg.c
@@ -27,6 +27,7 @@
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
*/
#include <sys/types.h>
@@ -1115,23 +1116,14 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
/*
- * If we are storing to a variable, generate an stv instruction from
- * the variable specified by the identifier. If we are storing to a
- * memory address, generate code again for the left-hand side using
- * DT_NF_REF to get the address, and then generate a store to it.
- * In both paths, we assume dnp->dn_reg already has the new value.
+ * If we are storing to a memory address, generate code again for the
+ * left-hand side using DT_NF_REF to get the address, and then generate
+ * a store to it.
+ *
+ * Both here and the other variable-store paths, we assume dnp->dn_reg
+ * already has the new value.
*/
- if (dnp->dn_left->dn_kind == DT_NODE_VAR) {
- idp = dt_ident_resolve(dnp->dn_left->dn_ident);
-
- if (idp->di_kind == DT_IDENT_ARRAY)
- dt_cg_arglist(idp, dnp->dn_left->dn_args, dlp, drp);
-
- idp->di_flags |= DT_IDFLG_DIFW;
- instr = DIF_INSTR_STV(dt_cg_stvar(idp),
- idp->di_id, dnp->dn_reg);
- dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- } else {
+ if (dnp->dn_left->dn_kind != DT_NODE_VAR) {
uint_t rbit = dnp->dn_left->dn_flags & DT_NF_REF;
assert(dnp->dn_left->dn_flags & DT_NF_WRITABLE);
@@ -1145,7 +1137,33 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dnp->dn_left->dn_flags &= ~DT_NF_REF;
dnp->dn_left->dn_flags |= rbit;
+ return;
}
+
+ idp = dt_ident_resolve(dnp->dn_left->dn_ident);
+ idp->di_flags |= DT_IDFLG_DIFW;
+
+ /*
+ * Storing to an array variable is a special case.
+ * Only 'uregs[]' supports this for the time being.
+ */
+ if (idp->di_kind == DT_IDENT_ARRAY &&
+ idp->di_id <= DIF_VAR_ARRAY_MAX) {
+ dt_node_t *idx = dnp->dn_left->dn_args;
+
+ dt_cg_node(idx, dlp, drp);
+ instr = DIF_INSTR_FMT(DIF_OP_STGA, idp->di_id, idx->dn_reg,
+ dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_regset_free(drp, idx->dn_reg);
+ return;
+ }
+
+ if (idp->di_kind == DT_IDENT_ARRAY)
+ dt_cg_arglist(idp, dnp->dn_left->dn_args, dlp, drp);
+
+ instr = DIF_INSTR_STV(dt_cg_stvar(idp), idp->di_id, dnp->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
}
static void
diff --git a/usr/src/lib/libdtrace/common/dt_decl.c b/usr/src/lib/libdtrace/common/dt_decl.c
index bbb561d027..c9bd469ddb 100644
--- a/usr/src/lib/libdtrace/common/dt_decl.c
+++ b/usr/src/lib/libdtrace/common/dt_decl.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
- * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ * Copyright (c) 2015 Joyent, Inc. All rights reserved.
*/
#include <strings.h>
@@ -652,7 +652,7 @@ dt_decl_member(dt_node_t *dnp)
}
if (ctf_add_member(dsp->ds_ctfp, dsp->ds_type,
- ident, dtt.dtt_type) == CTF_ERR) {
+ ident, dtt.dtt_type, ULONG_MAX) == CTF_ERR) {
xyerror(D_UNKNOWN, "failed to define member '%s': %s\n",
idname, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
}
diff --git a/usr/src/lib/libdtrace/common/dt_dis.c b/usr/src/lib/libdtrace/common/dt_dis.c
index c0af36420e..60195f3970 100644
--- a/usr/src/lib/libdtrace/common/dt_dis.c
+++ b/usr/src/lib/libdtrace/common/dt_dis.c
@@ -27,7 +27,7 @@
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
- * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017 Joyent, Inc.
*/
#include <strings.h>
@@ -47,7 +47,7 @@ dt_dis_log(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
/*ARGSUSED*/
static void
dt_dis_branch(const dtrace_difo_t *dp, const char *name,
- dif_instr_t in, FILE *fp)
+ dif_instr_t in, FILE *fp)
{
(void) fprintf(fp, "%-4s %u", name, DIF_INSTR_LABEL(in));
}
@@ -63,7 +63,7 @@ dt_dis_load(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
/*ARGSUSED*/
static void
dt_dis_store(const dtrace_difo_t *dp, const char *name,
- dif_instr_t in, FILE *fp)
+ dif_instr_t in, FILE *fp)
{
(void) fprintf(fp, "%-4s %%r%u, [%%r%u]", name,
DIF_INSTR_R1(in), DIF_INSTR_RD(in));
@@ -167,6 +167,19 @@ dt_dis_stv(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
}
static void
+dt_dis_sta(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
+{
+ uint_t var = DIF_INSTR_VAR(in);
+ const char *vname;
+
+ (void) fprintf(fp, "%-4s DT_VAR(%u), %%r%u, %%r%u",
+ name, var, DIF_INSTR_R2(in), DIF_INSTR_RD(in));
+
+ if ((vname = dt_dis_varname(dp, var, dt_dis_scope(name))) != NULL)
+ (void) fprintf(fp, "\t\t! DT_VAR(%u) = \"%s\"", var, vname);
+}
+
+static void
dt_dis_setx(const dtrace_difo_t *dp, const char *name, dif_instr_t in, FILE *fp)
{
uint_t intptr = DIF_INSTR_INTEGER(in);
@@ -428,6 +441,7 @@ dt_dis(const dtrace_difo_t *dp, FILE *fp)
{ "rldx", dt_dis_load }, /* DIF_OP_RLDX */
{ "xlate", dt_dis_xlate }, /* DIF_OP_XLATE */
{ "xlarg", dt_dis_xlate }, /* DIF_OP_XLARG */
+ { "stga", dt_dis_sta }, /* DIF_OP_XLARG */
};
const struct opent *op;
diff --git a/usr/src/lib/libdtrace/common/dt_impl.h b/usr/src/lib/libdtrace/common/dt_impl.h
index 2681709483..6841eca4e6 100644
--- a/usr/src/lib/libdtrace/common/dt_impl.h
+++ b/usr/src/lib/libdtrace/common/dt_impl.h
@@ -267,6 +267,7 @@ struct dtrace_hdl {
uint_t dt_droptags; /* boolean: set via -xdroptags */
uint_t dt_active; /* boolean: set once tracing is active */
uint_t dt_stopped; /* boolean: set once tracing is stopped */
+ uint_t dt_optset; /* boolean: set once options have been set */
processorid_t dt_beganon; /* CPU that executed BEGIN probe (if any) */
processorid_t dt_endedon; /* CPU that executed END probe (if any) */
uint_t dt_oflags; /* dtrace open-time options (see dtrace.h) */
diff --git a/usr/src/lib/libdtrace/common/dt_link.c b/usr/src/lib/libdtrace/common/dt_link.c
index e910ac3ff1..55d2fbd3bc 100644
--- a/usr/src/lib/libdtrace/common/dt_link.c
+++ b/usr/src/lib/libdtrace/common/dt_link.c
@@ -22,10 +22,9 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Mark Johnston.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#define ELF_TARGET_ALL
#include <elf.h>
@@ -1013,6 +1012,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
static const char dt_enabled[] = "enabled";
static const char dt_symprefix[] = "$dtrace";
static const char dt_symfmt[] = "%s%d.%s";
+ char probename[DTRACE_NAMELEN];
int fd, i, ndx, eprobe, mod = 0;
Elf *elf = NULL;
GElf_Ehdr ehdr;
@@ -1355,8 +1355,6 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
bcopy(s, pname, p - s);
pname[p - s] = '\0';
- p = strhyphenate(p + 3); /* strlen("___") */
-
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym) != 0)
goto err;
@@ -1406,9 +1404,17 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
"no such provider %s", pname));
}
- if ((prp = dt_probe_lookup(pvp, p)) == NULL) {
+ /* strlen("___") */
+ if (strlcpy(probename, p + 3, sizeof (probename)) >=
+ sizeof (probename))
+ return (dt_link_error(dtp, elf, fd, bufs,
+ "invalid probe name %s", probename));
+
+ (void) strhyphenate(probename);
+
+ if ((prp = dt_probe_lookup(pvp, probename)) == NULL) {
return (dt_link_error(dtp, elf, fd, bufs,
- "no such probe %s", p));
+ "no such probe %s", probename));
}
assert(fsym.st_value <= rela.r_offset);
diff --git a/usr/src/lib/libdtrace/common/dt_module.c b/usr/src/lib/libdtrace/common/dt_module.c
index 0288f329da..4c9a7ce66b 100644
--- a/usr/src/lib/libdtrace/common/dt_module.c
+++ b/usr/src/lib/libdtrace/common/dt_module.c
@@ -1372,6 +1372,77 @@ dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,
return (0);
}
+/*
+ * We've been asked to look up something inside a pid related module and it has
+ * been qualified with a library name. In that case, we may have to split this
+ * up into the library and the type itself, which will be separated by an '`'
+ * character. This is complicated further by the fact that the keyword for a
+ * struct, union, or enum, will precede the library. Hence we may have something
+ * that looks like "struct libsocket.so.1`msghdr" in name and we need to
+ * transform that into "libsocket.so.1" and "struct msghdr".
+ */
+int
+dtrace_lookup_fixup_pidtype(const char *name, char **libp, char **typep)
+{
+ int len, i;
+ char *split = NULL, *lib, *buf;
+ char *base;
+ char *keywords[] = { "struct ", "union ", "enum ", NULL };
+
+ if (name == NULL)
+ return (-1);
+
+ *libp = NULL;
+ *typep = NULL;
+ buf = strdup(name);
+ if (buf == NULL)
+ return (-1);
+
+ i = 0;
+ lib = buf;
+ while (keywords[i] != NULL) {
+ base = keywords[i];
+ len = strlen(base);
+ if (strncmp(name, base, len) == 0) {
+ lib += len;
+ break;
+ }
+ i++;
+ }
+
+ split = strchr(buf, '`');
+ assert(split != NULL);
+ *split = '\0';
+ split++;
+ if (lib == buf) {
+ *libp = strdup(buf);
+ *typep = strdup(split);
+ if (*libp == NULL || *typep == NULL)
+ goto err;
+ free(buf);
+ return (0);
+ } else {
+ assert(len > 0);
+ assert(base != NULL);
+
+ *libp = strdup(lib);
+ if (*libp == NULL)
+ goto err;
+ if (asprintf(typep, "%s%s", base, split) == -1)
+ goto err;
+ free(buf);
+ return (0);
+ }
+
+err:
+ free(buf);
+ free(*libp);
+ *libp = NULL;
+ free(*typep);
+ *typep = NULL;
+ return (-1);
+}
+
int
dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
dtrace_typeinfo_t *tip)
@@ -1383,7 +1454,6 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
uint_t n, i;
int justone;
ctf_file_t *fp;
- char *buf, *p, *q;
uint_t mask = 0; /* mask of dt_module flags to match */
uint_t bits = 0; /* flag bits that must be present */
@@ -1437,19 +1507,19 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
id = ctf_lookup_by_name(dmp->dm_ctfp, name);
fp = dmp->dm_ctfp;
} else {
- if ((p = strchr(name, '`')) != NULL) {
- buf = strdup(name);
- if (buf == NULL)
+ dt_dprintf("Trying to find userland type: %s\n", name);
+ if (strchr(name, '`') != NULL) {
+ char *lib, *type;
+ if (dtrace_lookup_fixup_pidtype(name, &lib,
+ &type) != 0) {
return (dt_set_errno(dtp, EDT_NOMEM));
- p = strchr(buf, '`');
- if ((q = strchr(p + 1, '`')) != NULL)
- p = q;
- *p = '\0';
- fp = dt_module_getctflib(dtp, dmp, buf);
+ }
+ fp = dt_module_getctflib(dtp, dmp, lib);
if (fp == NULL || (id = ctf_lookup_by_name(fp,
- p + 1)) == CTF_ERR)
+ type)) == CTF_ERR)
id = CTF_ERR;
- free(buf);
+ free(lib);
+ free(type);
} else {
for (i = 0; i < dmp->dm_nctflibs; i++) {
fp = dmp->dm_libctfp[i];
diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c
index 38c8146039..3325f333ab 100644
--- a/usr/src/lib/libdtrace/common/dt_open.c
+++ b/usr/src/lib/libdtrace/common/dt_open.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
@@ -40,6 +40,7 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
+#include <zone.h>
#define _POSIX_PTHREAD_SEMANTICS
#include <dirent.h>
@@ -427,8 +428,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_type, "uid_t" },
{ "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
-{ "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
- &dt_idops_regs, NULL },
+{ "uregs", DT_IDENT_ARRAY, DT_IDFLG_WRITE, DIF_VAR_UREGS, DT_ATTR_STABCMN,
+ DT_VERS_1_0, &dt_idops_regs, NULL },
{ "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "stack(...)" },
{ "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,
@@ -685,8 +686,8 @@ const dtrace_pattr_t _dtrace_prvdesc = {
{ DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
};
-const char *_dtrace_defcpp = "/usr/ccs/lib/cpp"; /* default cpp(1) to invoke */
-const char *_dtrace_defld = "/usr/ccs/bin/ld"; /* default ld(1) to invoke */
+const char *_dtrace_defcpp = "/usr/lib/cpp"; /* default cpp(1) to invoke */
+const char *_dtrace_defld = "/usr/bin/ld"; /* default ld(1) to invoke */
const char *_dtrace_libdir = "/usr/lib/dtrace"; /* default library directory */
const char *_dtrace_provdir = "/dev/dtrace/provider"; /* provider directory */
@@ -826,6 +827,8 @@ dt_vopen(int version, int flags, int *errp,
dt_provmod_t *provmod = NULL;
int i, err;
struct rlimit rl;
+ const char *zroot;
+ char *libpath = NULL;
const dt_intrinsic_t *dinp;
const dt_typedef_t *dtyp;
@@ -958,11 +961,19 @@ alloc:
dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *));
dt_proc_init(dtp);
dtp->dt_vmax = DT_VERS_LATEST;
- dtp->dt_cpp_path = strdup(_dtrace_defcpp);
+ zroot = zone_get_nroot();
+ if (zroot != NULL) {
+ (void) asprintf(&dtp->dt_ld_path, "%s/%s", zroot,
+ _dtrace_defld);
+ (void) asprintf(&dtp->dt_cpp_path, "%s/%s", zroot,
+ _dtrace_defcpp);
+ } else {
+ dtp->dt_ld_path = strdup(_dtrace_defld);
+ dtp->dt_cpp_path = strdup(_dtrace_defcpp);
+ }
dtp->dt_cpp_argv = malloc(sizeof (char *));
dtp->dt_cpp_argc = 1;
dtp->dt_cpp_args = 1;
- dtp->dt_ld_path = strdup(_dtrace_defld);
dtp->dt_provmod = provmod;
dtp->dt_vector = vector;
dtp->dt_varg = arg;
@@ -1136,13 +1147,13 @@ alloc:
* Add intrinsic pointer types that are needed to initialize printf
* format dictionary types (see table in dt_printf.c).
*/
- (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, NULL,
ctf_lookup_by_name(dmp->dm_ctfp, "void"));
- (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, NULL,
ctf_lookup_by_name(dmp->dm_ctfp, "char"));
- (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
+ (void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, NULL,
ctf_lookup_by_name(dmp->dm_ctfp, "int"));
if (ctf_update(dmp->dm_ctfp) != 0) {
@@ -1202,11 +1213,11 @@ alloc:
ctc.ctc_argc = 0;
ctc.ctc_flags = 0;
- dtp->dt_type_func = ctf_add_function(dmp->dm_ctfp,
+ dtp->dt_type_func = ctf_add_funcptr(dmp->dm_ctfp,
CTF_ADD_ROOT, &ctc, NULL);
- dtp->dt_type_fptr = ctf_add_pointer(dmp->dm_ctfp,
- CTF_ADD_ROOT, dtp->dt_type_func);
+ dtp->dt_type_fptr = ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, NULL,
+ dtp->dt_type_func);
/*
* We also insert CTF definitions for the special D intrinsic types
@@ -1307,9 +1318,15 @@ alloc:
* compile, and to provide better error reporting (because the full
* reporting of compiler errors requires dtrace_open() to succeed).
*/
- if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)
+ if (zroot != NULL)
+ (void) asprintf(&libpath, "%s/%s", zroot, _dtrace_libdir);
+ if (dtrace_setopt(dtp, "libdir",
+ libpath != NULL ? libpath : _dtrace_libdir) != 0)
return (set_open_errno(dtp, errp, dtp->dt_errno));
+ if (libpath != NULL)
+ free(libpath);
+
return (dtp);
}
diff --git a/usr/src/lib/libdtrace/common/dt_options.c b/usr/src/lib/libdtrace/common/dt_options.c
index 201b50a177..be985d6dab 100644
--- a/usr/src/lib/libdtrace/common/dt_options.c
+++ b/usr/src/lib/libdtrace/common/dt_options.c
@@ -41,6 +41,8 @@
#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
+#include <zone.h>
+#include <libzonecfg.h>
#include <dt_impl.h>
#include <dt_string.h>
@@ -854,6 +856,44 @@ dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
return (0);
}
+/*ARGSUSED*/
+static int
+dt_opt_zone(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+ zoneid_t z, did;
+
+ if (arg == NULL)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+ /*
+ * If the specified zone is currently running, we'll query the kernel
+ * for its debugger ID. If it doesn't appear to be running, we'll look
+ * for it for among all installed zones (thereby allowing a zdefs
+ * enabling against a halted zone).
+ */
+ if ((z = getzoneidbyname(arg)) != -1) {
+ if (zone_getattr(z, ZONE_ATTR_DID, &did, sizeof (did)) < 0)
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+ } else {
+ zone_dochandle_t handle;
+
+ if ((handle = zonecfg_init_handle()) == NULL)
+ return (dt_set_errno(dtp, errno));
+
+ if (zonecfg_get_handle(arg, handle) != Z_OK) {
+ zonecfg_fini_handle(handle);
+ return (dt_set_errno(dtp, EDT_BADOPTVAL));
+ }
+
+ did = zonecfg_get_did(handle);
+ zonecfg_fini_handle(handle);
+ }
+
+ dtp->dt_options[DTRACEOPT_ZONE] = did;
+
+ return (0);
+}
+
int
dt_options_load(dtrace_hdl_t *dtp)
{
@@ -988,6 +1028,7 @@ static const dt_option_t _dtrace_rtoptions[] = {
{ "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
{ "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
{ "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
+ { "zone", dt_opt_zone, DTRACEOPT_ZONE },
{ "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
{ NULL }
};
@@ -1068,9 +1109,41 @@ dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
if (dtp->dt_active)
return (dt_set_errno(dtp, EDT_ACTIVE));
+ /*
+ * If our options had been previously ioctl'd down,
+ * clear dt_optset to indicate that a run-time option
+ * has since been set.
+ */
+ dtp->dt_optset = B_FALSE;
+
return (op->o_func(dtp, val, op->o_option));
}
}
return (dt_set_errno(dtp, EDT_BADOPTNAME));
}
+
+int
+dtrace_setopts(dtrace_hdl_t *dtp)
+{
+ void *dof;
+ int err;
+
+ if (dtp->dt_optset)
+ return (0);
+
+ if ((dof = dtrace_getopt_dof(dtp)) == NULL)
+ return (-1); /* dt_errno has been set for us */
+
+ if ((err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof)) == -1)
+ (void) dt_set_errno(dtp, errno);
+
+ dtrace_dof_destroy(dtp, dof);
+
+ if (err == -1)
+ return (-1);
+
+ dtp->dt_optset = B_TRUE;
+
+ return (0);
+}
diff --git a/usr/src/lib/libdtrace/common/dt_parser.c b/usr/src/lib/libdtrace/common/dt_parser.c
index 7f771a8079..e652f337d9 100644
--- a/usr/src/lib/libdtrace/common/dt_parser.c
+++ b/usr/src/lib/libdtrace/common/dt_parser.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent Inc. All rights reserved.
+ * Copyright (c) 2015, Joyent Inc. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
@@ -288,7 +288,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip)
return (dt_set_errno(dtp, EDT_CTF));
}
- ptr = ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, type);
+ ptr = ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, NULL, type);
if (ptr == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
diff --git a/usr/src/lib/libdtrace/common/dt_program.c b/usr/src/lib/libdtrace/common/dt_program.c
index 7d725bd0af..e4f9d8dd1c 100644
--- a/usr/src/lib/libdtrace/common/dt_program.c
+++ b/usr/src/lib/libdtrace/common/dt_program.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
@@ -154,6 +155,14 @@ dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
void *dof;
int n, err;
+ /*
+ * If we have not yet ioctl'd down our options DOF, we'll do that
+ * before enabling any probes (some options will affect which probes
+ * we match).
+ */
+ if (dtrace_setopts(dtp) != 0)
+ return (-1);
+
dtrace_program_info(dtp, pgp, pip);
if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL)
diff --git a/usr/src/lib/libdtrace/common/dt_work.c b/usr/src/lib/libdtrace/common/dt_work.c
index 97a7f62d69..c330394027 100644
--- a/usr/src/lib/libdtrace/common/dt_work.c
+++ b/usr/src/lib/libdtrace/common/dt_work.c
@@ -25,7 +25,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
#include <dt_impl.h>
#include <stddef.h>
@@ -164,13 +166,22 @@ dtrace_status(dtrace_hdl_t *dtp)
int
dtrace_go(dtrace_hdl_t *dtp)
{
- void *dof;
- int err;
-
if (dtp->dt_active)
return (dt_set_errno(dtp, EINVAL));
/*
+ * In most cases, we will have already ioctl'd down our options DOF
+ * by this point -- but if a libdtrace does a dtrace_setopt() after
+ * calling dtrace_program_exec() but before calling dtrace_go(),
+ * dt_optset will be cleared and we need to ioctl down the options
+ * DOF now.
+ */
+ if (dtrace_setopts(dtp) != 0 &&
+ (dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL)) {
+ return (-1);
+ }
+
+ /*
* If a dtrace:::ERROR program and callback are registered, enable the
* program before we start tracing. If this fails for a vector open
* with ENOTTY, we permit dtrace_go() to succeed so that vector clients
@@ -178,19 +189,10 @@ dtrace_go(dtrace_hdl_t *dtp)
* though they do not provide support for the DTRACEIOC_ENABLE ioctl.
*/
if (dtp->dt_errprog != NULL &&
- dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && (
- dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL))
- return (-1); /* dt_errno has been set for us */
-
- if ((dof = dtrace_getopt_dof(dtp)) == NULL)
+ dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 &&
+ (dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL))
return (-1); /* dt_errno has been set for us */
- err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof);
- dtrace_dof_destroy(dtp, dof);
-
- if (err == -1 && (errno != ENOTTY || dtp->dt_vector == NULL))
- return (dt_set_errno(dtp, errno));
-
if (dt_ioctl(dtp, DTRACEIOC_GO, &dtp->dt_beganon) == -1) {
if (errno == EACCES)
return (dt_set_errno(dtp, EDT_DESTRUCTIVE));
diff --git a/usr/src/lib/libdtrace/common/dtrace.h b/usr/src/lib/libdtrace/common/dtrace.h
index 293ab944af..dd591296aa 100644
--- a/usr/src/lib/libdtrace/common/dtrace.h
+++ b/usr/src/lib/libdtrace/common/dtrace.h
@@ -83,6 +83,7 @@ extern const char *dtrace_subrstr(dtrace_hdl_t *, int);
extern int dtrace_setopt(dtrace_hdl_t *, const char *, const char *);
extern int dtrace_getopt(dtrace_hdl_t *, const char *, dtrace_optval_t *);
+extern int dtrace_setopts(dtrace_hdl_t *);
extern void dtrace_update(dtrace_hdl_t *);
extern int dtrace_ctlfd(dtrace_hdl_t *);
diff --git a/usr/src/lib/libdtrace/common/mac.d.in b/usr/src/lib/libdtrace/common/mac.d.in
new file mode 100644
index 0000000000..6263d51bdd
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/mac.d.in
@@ -0,0 +1,66 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ */
+
+#pragma D depends_on library ip.d
+
+inline int ETHERTYPE_PUP = @ETHERTYPE_PUP@;
+inline int ETHERTYPE_802_MIN = @ETHERTYPE_802_MIN@;
+inline int ETHERTYPE_IP = @ETHERTYPE_IP@;
+inline int ETHERTYPE_ARP = @ETHERTYPE_ARP@;
+inline int ETHERTYPE_REVARP = @ETHERTYPE_REVARP@;
+inline int ETHERTYPE_AT = @ETHERTYPE_AT@;
+inline int ETHERTYPE_AARP = @ETHERTYPE_AARP@;
+inline int ETHERTYPE_VLAN = @ETHERTYPE_VLAN@;
+inline int ETHERTYPE_IPV6 = @ETHERTYPE_IPV6@;
+inline int ETHERTYPE_SLOW = @ETHERTYPE_SLOW@;
+inline int ETHERTYPE_PPPOED = @ETHERTYPE_PPPOED@;
+inline int ETHERTYPE_PPPOES = @ETHERTYPE_PPPOES@;
+inline int ETHERTYPE_EAPOL = @ETHERTYPE_EAPOL@;
+inline int ETHERTYPE_RSN_PREAUTH = @ETHERTYPE_RSN_PREAUTH@;
+inline int ETHERTYPE_TRILL = @ETHERTYPE_TRILL@;
+inline int ETHERTYPE_FCOE = @ETHERTYPE_FCOE@;
+inline int ETHERTYPE_MAX = @ETHERTYPE_MAX@;
+
+
+typedef struct etherinfo {
+ uint8_t eth_dst[6]; /* Destination MAC addr */
+ uint8_t eth_src[6]; /* Source MAC addr */
+ uint16_t eth_type; /* Ethertype */
+ boolean_t eth_istagged; /* Is the VLAN tag present */
+ uint8_t eth_priority; /* Priority tag */
+ uint8_t eth_dei; /* drop eligible indicator */
+ uint16_t eth_vlanid; /* VLAN ID */
+ uintptr_t eth_header; /* Pointer to start of header */
+ uintptr_t eth_mblk; /* Pointer to the mblk containing header */
+} etherinfo_t;
+
+#pragma D binding "1.12.1" translator
+translator etherinfo_t < mblk_t *mp > {
+ eth_dst = mp->b_rptr;
+ eth_src = mp->b_rptr + 6;
+ eth_type = ntohs(*(uint16_t *)(mp->b_rptr + 12)) == ETHERTYPE_VLAN ?
+ ntohs(*(uint16_t *)(mp->b_rptr + 16)) :
+ ntohs(*(uint16_t *)(mp->b_rptr + 12));
+ eth_istagged = ntohs(*(uint16_t *)(mp->b_rptr + 12)) == ETHERTYPE_VLAN ?
+ 1 : 0;
+ eth_priority = ntohs(*(uint16_t *)(mp->b_rptr + 12)) == ETHERTYPE_VLAN ?
+ ntohs(*(uint16_t *)(mp->b_rptr + 14)) & 0xe000: 0;
+ eth_dei = ntohs(*(uint16_t *)(mp->b_rptr + 12)) == ETHERTYPE_VLAN ?
+ ntohs(*(uint16_t *)(mp->b_rptr + 14)) & 0x1000: 0;
+ eth_vlanid = ntohs(*(uint16_t *)(mp->b_rptr + 12)) == ETHERTYPE_VLAN ?
+ ntohs(*(uint16_t *)(mp->b_rptr + 14)) & 0x0fff: 0;
+ eth_header = (uintptr_t)mp->b_rptr;
+ eth_mblk = (uintptr_t)mp;
+};
diff --git a/usr/src/lib/libdtrace/common/mac.sed.in b/usr/src/lib/libdtrace/common/mac.sed.in
new file mode 100644
index 0000000000..00e149d000
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/mac.sed.in
@@ -0,0 +1,45 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ */
+
+
+/*
+ * This file is a sed script which is first preprocessed by cpp or cc -E to
+ * define a set of sed directives which replace #define tokens with their
+ * values. After preprocessing, the sed script is run over vnd.d.in to
+ * replace the #define tokens listed below to create the finished vnd.d.
+ * Refer to the rules in libdtrace/Makefile.com for more information.
+ */
+
+#include <sys/ethernet.h>
+
+#define SED_REPLACE(x) s/#x/x/g
+
+SED_REPLACE(ETHERTYPE_PUP)
+SED_REPLACE(ETHERTYPE_802_MIN)
+SED_REPLACE(ETHERTYPE_IP)
+SED_REPLACE(ETHERTYPE_ARP)
+SED_REPLACE(ETHERTYPE_REVARP)
+SED_REPLACE(ETHERTYPE_AT)
+SED_REPLACE(ETHERTYPE_AARP)
+SED_REPLACE(ETHERTYPE_VLAN)
+SED_REPLACE(ETHERTYPE_IPV6)
+SED_REPLACE(ETHERTYPE_SLOW)
+SED_REPLACE(ETHERTYPE_PPPOED)
+SED_REPLACE(ETHERTYPE_PPPOES)
+SED_REPLACE(ETHERTYPE_EAPOL)
+SED_REPLACE(ETHERTYPE_RSN_PREAUTH)
+SED_REPLACE(ETHERTYPE_TRILL)
+SED_REPLACE(ETHERTYPE_FCOE)
+SED_REPLACE(ETHERTYPE_MAX)
diff --git a/usr/src/lib/libdtrace/common/vnd.d b/usr/src/lib/libdtrace/common/vnd.d
new file mode 100644
index 0000000000..356c412150
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/vnd.d
@@ -0,0 +1,28 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ */
+
+
+#pragma D depends_on module vnd
+#pragma D depends_on provider vnd
+#pragma D depends_on library ip.d
+#pragma D depends_on library mac.d
+
+#pragma D binding "1.6.3" translator
+translator ifinfo_t < vnd_str_t *vsp > {
+ if_name = vsp != NULL ? stringof(vsp->vns_dev->vdd_lname) : "<null>";
+ if_local = 0;
+ if_ipstack = vsp != NULL ? vsp->vns_nsd->vpnd_nsid : 0;
+ if_addr = (uintptr_t)vsp;
+};