diff options
Diffstat (limited to 'usr/src/lib/libdtrace/common')
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_cg.c | 50 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_decl.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_dis.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_impl.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_link.c | 18 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_module.c | 92 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_open.c | 45 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_options.c | 73 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_parser.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_program.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dt_work.c | 32 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/dtrace.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/mac.d.in | 66 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/mac.sed.in | 45 | ||||
-rw-r--r-- | usr/src/lib/libdtrace/common/vnd.d | 28 |
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; +}; |