1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/resource.h> 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <strings.h> 33*7c478bd9Sstevel@tonic-gate #include <signal.h> 34*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 35*7c478bd9Sstevel@tonic-gate #include <unistd.h> 36*7c478bd9Sstevel@tonic-gate #include <limits.h> 37*7c478bd9Sstevel@tonic-gate #include <alloca.h> 38*7c478bd9Sstevel@tonic-gate #include <errno.h> 39*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include <dt_impl.h> 42*7c478bd9Sstevel@tonic-gate #include <dt_string.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static int 45*7c478bd9Sstevel@tonic-gate dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 46*7c478bd9Sstevel@tonic-gate { 47*7c478bd9Sstevel@tonic-gate dt_aggregate_t *agp = &dtp->dt_aggregate; 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate if (arg != NULL) 50*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate agp->dtat_flags |= option; 53*7c478bd9Sstevel@tonic-gate return (0); 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 57*7c478bd9Sstevel@tonic-gate static int 58*7c478bd9Sstevel@tonic-gate dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 59*7c478bd9Sstevel@tonic-gate { 60*7c478bd9Sstevel@tonic-gate char str[DTRACE_ATTR2STR_MAX]; 61*7c478bd9Sstevel@tonic-gate dtrace_attribute_t attr; 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate if (arg == NULL || dtrace_str2attr(arg, &attr) == -1) 64*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate dt_dprintf("set compiler attribute minimum to %s\n", 67*7c478bd9Sstevel@tonic-gate dtrace_attr2str(attr, str, sizeof (str))); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) { 70*7c478bd9Sstevel@tonic-gate dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR; 71*7c478bd9Sstevel@tonic-gate dtp->dt_pcb->pcb_amin = attr; 72*7c478bd9Sstevel@tonic-gate } else { 73*7c478bd9Sstevel@tonic-gate dtp->dt_cflags |= DTRACE_C_EATTR; 74*7c478bd9Sstevel@tonic-gate dtp->dt_amin = attr; 75*7c478bd9Sstevel@tonic-gate } 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate return (0); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate static void 81*7c478bd9Sstevel@tonic-gate dt_coredump(void) 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n"; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate struct sigaction act; 86*7c478bd9Sstevel@tonic-gate struct rlimit lim; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate (void) write(STDERR_FILENO, msg, sizeof (msg) - 1); 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate act.sa_handler = SIG_DFL; 91*7c478bd9Sstevel@tonic-gate act.sa_flags = 0; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&act.sa_mask); 94*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGABRT, &act, NULL); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate lim.rlim_cur = RLIM_INFINITY; 97*7c478bd9Sstevel@tonic-gate lim.rlim_max = RLIM_INFINITY; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate (void) setrlimit(RLIMIT_CORE, &lim); 100*7c478bd9Sstevel@tonic-gate abort(); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 104*7c478bd9Sstevel@tonic-gate static int 105*7c478bd9Sstevel@tonic-gate dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 106*7c478bd9Sstevel@tonic-gate { 107*7c478bd9Sstevel@tonic-gate static int enabled = 0; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate if (arg != NULL) 110*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate if (enabled++ || atexit(dt_coredump) == 0) 113*7c478bd9Sstevel@tonic-gate return (0); 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, errno)); 116*7c478bd9Sstevel@tonic-gate } 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 119*7c478bd9Sstevel@tonic-gate static int 120*7c478bd9Sstevel@tonic-gate dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate if (arg != NULL) 123*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 126*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTCTX)); 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate if (dt_cpp_add_arg(dtp, "-H") == NULL) 129*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate return (0); 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 135*7c478bd9Sstevel@tonic-gate static int 136*7c478bd9Sstevel@tonic-gate dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate char *cpp; 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate if (arg == NULL) 141*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 144*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTCTX)); 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate if ((cpp = strdup(arg)) == NULL) 147*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate dtp->dt_cpp_argv[0] = (char *)strbasename(cpp); 150*7c478bd9Sstevel@tonic-gate free(dtp->dt_cpp_path); 151*7c478bd9Sstevel@tonic-gate dtp->dt_cpp_path = cpp; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate return (0); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate static int 157*7c478bd9Sstevel@tonic-gate dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate char *buf; 160*7c478bd9Sstevel@tonic-gate size_t len; 161*7c478bd9Sstevel@tonic-gate const char *opt = (const char *)option; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate if (opt == NULL || arg == NULL) 164*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 167*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTCTX)); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate len = strlen(opt) + strlen(arg) + 1; 170*7c478bd9Sstevel@tonic-gate buf = alloca(len); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, opt); 173*7c478bd9Sstevel@tonic-gate (void) strcat(buf, arg); 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if (dt_cpp_add_arg(dtp, buf) == NULL) 176*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate return (0); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 182*7c478bd9Sstevel@tonic-gate static int 183*7c478bd9Sstevel@tonic-gate dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate int fd; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if (arg == NULL) 188*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 191*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, errno)); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate (void) close(dtp->dt_cdefs_fd); 194*7c478bd9Sstevel@tonic-gate dtp->dt_cdefs_fd = fd; 195*7c478bd9Sstevel@tonic-gate return (0); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 199*7c478bd9Sstevel@tonic-gate static int 200*7c478bd9Sstevel@tonic-gate dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 201*7c478bd9Sstevel@tonic-gate { 202*7c478bd9Sstevel@tonic-gate int fd; 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate if (arg == NULL) 205*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 208*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, errno)); 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate (void) close(dtp->dt_ddefs_fd); 211*7c478bd9Sstevel@tonic-gate dtp->dt_ddefs_fd = fd; 212*7c478bd9Sstevel@tonic-gate return (0); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 216*7c478bd9Sstevel@tonic-gate static int 217*7c478bd9Sstevel@tonic-gate dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 218*7c478bd9Sstevel@tonic-gate { 219*7c478bd9Sstevel@tonic-gate if (arg != NULL) 220*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate _dtrace_debug = 1; 223*7c478bd9Sstevel@tonic-gate return (0); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 227*7c478bd9Sstevel@tonic-gate static int 228*7c478bd9Sstevel@tonic-gate dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate int n; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (arg == NULL || (n = atoi(arg)) <= 0) 233*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate dtp->dt_conf.dtc_difintregs = n; 236*7c478bd9Sstevel@tonic-gate return (0); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 240*7c478bd9Sstevel@tonic-gate static int 241*7c478bd9Sstevel@tonic-gate dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 242*7c478bd9Sstevel@tonic-gate { 243*7c478bd9Sstevel@tonic-gate dtp->dt_lazyload = 1; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate return (0); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 249*7c478bd9Sstevel@tonic-gate static int 250*7c478bd9Sstevel@tonic-gate dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 251*7c478bd9Sstevel@tonic-gate { 252*7c478bd9Sstevel@tonic-gate char *ld; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate if (arg == NULL) 255*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 258*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTCTX)); 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate if ((ld = strdup(arg)) == NULL) 261*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate free(dtp->dt_ld_path); 264*7c478bd9Sstevel@tonic-gate dtp->dt_ld_path = ld; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate return (0); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 270*7c478bd9Sstevel@tonic-gate static int 271*7c478bd9Sstevel@tonic-gate dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate dt_dirpath_t *dp; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (arg == NULL) 276*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL || 279*7c478bd9Sstevel@tonic-gate (dp->dir_path = strdup(arg)) == NULL) { 280*7c478bd9Sstevel@tonic-gate free(dp); 281*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate dt_list_append(&dtp->dt_lib_path, dp); 285*7c478bd9Sstevel@tonic-gate return (0); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 289*7c478bd9Sstevel@tonic-gate static int 290*7c478bd9Sstevel@tonic-gate dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 291*7c478bd9Sstevel@tonic-gate { 292*7c478bd9Sstevel@tonic-gate if (arg == NULL) 293*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate if (strcmp(arg, "kernel") == 0) 296*7c478bd9Sstevel@tonic-gate dtp->dt_linkmode = DT_LINK_KERNEL; 297*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "primary") == 0) 298*7c478bd9Sstevel@tonic-gate dtp->dt_linkmode = DT_LINK_PRIMARY; 299*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "dynamic") == 0) 300*7c478bd9Sstevel@tonic-gate dtp->dt_linkmode = DT_LINK_DYNAMIC; 301*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "static") == 0) 302*7c478bd9Sstevel@tonic-gate dtp->dt_linkmode = DT_LINK_STATIC; 303*7c478bd9Sstevel@tonic-gate else 304*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate return (0); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 310*7c478bd9Sstevel@tonic-gate static int 311*7c478bd9Sstevel@tonic-gate dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 312*7c478bd9Sstevel@tonic-gate { 313*7c478bd9Sstevel@tonic-gate if (arg == NULL) 314*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate if (strcasecmp(arg, "elf") == 0) 317*7c478bd9Sstevel@tonic-gate dtp->dt_linktype = DT_LTYP_ELF; 318*7c478bd9Sstevel@tonic-gate else if (strcasecmp(arg, "dof") == 0) 319*7c478bd9Sstevel@tonic-gate dtp->dt_linktype = DT_LTYP_DOF; 320*7c478bd9Sstevel@tonic-gate else 321*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate return (0); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 327*7c478bd9Sstevel@tonic-gate static int 328*7c478bd9Sstevel@tonic-gate dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 329*7c478bd9Sstevel@tonic-gate { 330*7c478bd9Sstevel@tonic-gate if (arg == NULL) 331*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate if (strcmp(arg, "exec") == 0) 334*7c478bd9Sstevel@tonic-gate dtp->dt_prcmode = DT_PROC_STOP_CREATE; 335*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "preinit") == 0) 336*7c478bd9Sstevel@tonic-gate dtp->dt_prcmode = DT_PROC_STOP_PREINIT; 337*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "postinit") == 0) 338*7c478bd9Sstevel@tonic-gate dtp->dt_prcmode = DT_PROC_STOP_POSTINIT; 339*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "main") == 0) 340*7c478bd9Sstevel@tonic-gate dtp->dt_prcmode = DT_PROC_STOP_MAIN; 341*7c478bd9Sstevel@tonic-gate else 342*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate return (0); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 348*7c478bd9Sstevel@tonic-gate static int 349*7c478bd9Sstevel@tonic-gate dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 350*7c478bd9Sstevel@tonic-gate { 351*7c478bd9Sstevel@tonic-gate int n; 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate if (arg == NULL || (n = atoi(arg)) < 0) 354*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate dtp->dt_procs->dph_lrulim = n; 357*7c478bd9Sstevel@tonic-gate return (0); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 361*7c478bd9Sstevel@tonic-gate static int 362*7c478bd9Sstevel@tonic-gate dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 363*7c478bd9Sstevel@tonic-gate { 364*7c478bd9Sstevel@tonic-gate if (arg == NULL) 365*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 368*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTCTX)); 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate if (strcmp(arg, "a") == 0) 371*7c478bd9Sstevel@tonic-gate dtp->dt_stdcmode = DT_STDC_XA; 372*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "c") == 0) 373*7c478bd9Sstevel@tonic-gate dtp->dt_stdcmode = DT_STDC_XC; 374*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "s") == 0) 375*7c478bd9Sstevel@tonic-gate dtp->dt_stdcmode = DT_STDC_XS; 376*7c478bd9Sstevel@tonic-gate else if (strcmp(arg, "t") == 0) 377*7c478bd9Sstevel@tonic-gate dtp->dt_stdcmode = DT_STDC_XT; 378*7c478bd9Sstevel@tonic-gate else 379*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate return (0); 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 385*7c478bd9Sstevel@tonic-gate static int 386*7c478bd9Sstevel@tonic-gate dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 387*7c478bd9Sstevel@tonic-gate { 388*7c478bd9Sstevel@tonic-gate dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path); 389*7c478bd9Sstevel@tonic-gate char *path; 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate if (arg == NULL) 392*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate if ((path = strdup(arg)) == NULL) 395*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate free(dp->dir_path); 398*7c478bd9Sstevel@tonic-gate dp->dir_path = path; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate return (0); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 405*7c478bd9Sstevel@tonic-gate static int 406*7c478bd9Sstevel@tonic-gate dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate int m; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if (arg == NULL || (m = atoi(arg)) <= 0) 411*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate dtp->dt_treedump = m; 414*7c478bd9Sstevel@tonic-gate return (0); 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 418*7c478bd9Sstevel@tonic-gate static int 419*7c478bd9Sstevel@tonic-gate dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 420*7c478bd9Sstevel@tonic-gate { 421*7c478bd9Sstevel@tonic-gate int n; 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate if (arg == NULL || (n = atoi(arg)) <= 0) 424*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate dtp->dt_conf.dtc_diftupregs = n; 427*7c478bd9Sstevel@tonic-gate return (0); 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate static int 431*7c478bd9Sstevel@tonic-gate dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 432*7c478bd9Sstevel@tonic-gate { 433*7c478bd9Sstevel@tonic-gate if (arg != NULL) 434*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 437*7c478bd9Sstevel@tonic-gate dtp->dt_pcb->pcb_cflags |= option; 438*7c478bd9Sstevel@tonic-gate else 439*7c478bd9Sstevel@tonic-gate dtp->dt_cflags |= option; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate return (0); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate static int 445*7c478bd9Sstevel@tonic-gate dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 446*7c478bd9Sstevel@tonic-gate { 447*7c478bd9Sstevel@tonic-gate if (arg != NULL) 448*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate dtp->dt_dflags |= option; 451*7c478bd9Sstevel@tonic-gate return (0); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate static int 455*7c478bd9Sstevel@tonic-gate dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 456*7c478bd9Sstevel@tonic-gate { 457*7c478bd9Sstevel@tonic-gate if (arg != NULL) 458*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate if (dtp->dt_pcb != NULL) 461*7c478bd9Sstevel@tonic-gate dtp->dt_pcb->pcb_cflags &= ~option; 462*7c478bd9Sstevel@tonic-gate else 463*7c478bd9Sstevel@tonic-gate dtp->dt_cflags &= ~option; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate return (0); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 469*7c478bd9Sstevel@tonic-gate static int 470*7c478bd9Sstevel@tonic-gate dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 471*7c478bd9Sstevel@tonic-gate { 472*7c478bd9Sstevel@tonic-gate dt_version_t v; 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate if (arg == NULL) 475*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate if (dt_version_str2num(arg, &v) == -1) 478*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_VERSINVAL)); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate if (!dt_version_defined(v)) 481*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_VERSUNDEF)); 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate return (dt_reduce(dtp, v)); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate static int 487*7c478bd9Sstevel@tonic-gate dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate char *end; 490*7c478bd9Sstevel@tonic-gate dtrace_optval_t val = 0; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate if (arg != NULL) { 493*7c478bd9Sstevel@tonic-gate errno = 0; 494*7c478bd9Sstevel@tonic-gate val = strtoull(arg, &end, 0); 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate if (*end != '\0' || errno != 0 || val < 0) 497*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 501*7c478bd9Sstevel@tonic-gate return (0); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate static int 505*7c478bd9Sstevel@tonic-gate dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 506*7c478bd9Sstevel@tonic-gate { 507*7c478bd9Sstevel@tonic-gate char *end; 508*7c478bd9Sstevel@tonic-gate int len; 509*7c478bd9Sstevel@tonic-gate dtrace_optval_t mul = 1, val = 0; 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate if (arg != NULL) { 512*7c478bd9Sstevel@tonic-gate len = strlen(arg); 513*7c478bd9Sstevel@tonic-gate errno = 0; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate switch (arg[len - 1]) { 516*7c478bd9Sstevel@tonic-gate case 't': 517*7c478bd9Sstevel@tonic-gate case 'T': 518*7c478bd9Sstevel@tonic-gate mul *= 1024; 519*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 520*7c478bd9Sstevel@tonic-gate case 'g': 521*7c478bd9Sstevel@tonic-gate case 'G': 522*7c478bd9Sstevel@tonic-gate mul *= 1024; 523*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 524*7c478bd9Sstevel@tonic-gate case 'm': 525*7c478bd9Sstevel@tonic-gate case 'M': 526*7c478bd9Sstevel@tonic-gate mul *= 1024; 527*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 528*7c478bd9Sstevel@tonic-gate case 'k': 529*7c478bd9Sstevel@tonic-gate case 'K': 530*7c478bd9Sstevel@tonic-gate mul *= 1024; 531*7c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 532*7c478bd9Sstevel@tonic-gate default: 533*7c478bd9Sstevel@tonic-gate break; 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate val = strtoull(arg, &end, 0) * mul; 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate if ((mul > 1 && end != &arg[len - 1]) || 539*7c478bd9Sstevel@tonic-gate (mul == 1 && *end != '\0') || val < 0 || 540*7c478bd9Sstevel@tonic-gate errno != 0 || val == DTRACEOPT_UNSET) 541*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 545*7c478bd9Sstevel@tonic-gate return (0); 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate static int 549*7c478bd9Sstevel@tonic-gate dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 550*7c478bd9Sstevel@tonic-gate { 551*7c478bd9Sstevel@tonic-gate char *end; 552*7c478bd9Sstevel@tonic-gate int i; 553*7c478bd9Sstevel@tonic-gate dtrace_optval_t mul = 1, val = 0; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate const struct { 556*7c478bd9Sstevel@tonic-gate char *name; 557*7c478bd9Sstevel@tonic-gate hrtime_t mul; 558*7c478bd9Sstevel@tonic-gate } suffix[] = { 559*7c478bd9Sstevel@tonic-gate { "ns", NANOSEC / NANOSEC }, 560*7c478bd9Sstevel@tonic-gate { "nsec", NANOSEC / NANOSEC }, 561*7c478bd9Sstevel@tonic-gate { "us", NANOSEC / MICROSEC }, 562*7c478bd9Sstevel@tonic-gate { "usec", NANOSEC / MICROSEC }, 563*7c478bd9Sstevel@tonic-gate { "ms", NANOSEC / MILLISEC }, 564*7c478bd9Sstevel@tonic-gate { "msec", NANOSEC / MILLISEC }, 565*7c478bd9Sstevel@tonic-gate { "s", NANOSEC / SEC }, 566*7c478bd9Sstevel@tonic-gate { "sec", NANOSEC / SEC }, 567*7c478bd9Sstevel@tonic-gate { "m", NANOSEC * (hrtime_t)60 }, 568*7c478bd9Sstevel@tonic-gate { "min", NANOSEC * (hrtime_t)60 }, 569*7c478bd9Sstevel@tonic-gate { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 570*7c478bd9Sstevel@tonic-gate { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 571*7c478bd9Sstevel@tonic-gate { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 572*7c478bd9Sstevel@tonic-gate { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 573*7c478bd9Sstevel@tonic-gate { "hz", 0 }, 574*7c478bd9Sstevel@tonic-gate { NULL } 575*7c478bd9Sstevel@tonic-gate }; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate if (arg != NULL) { 578*7c478bd9Sstevel@tonic-gate errno = 0; 579*7c478bd9Sstevel@tonic-gate val = strtoull(arg, &end, 0); 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate for (i = 0; suffix[i].name != NULL; i++) { 582*7c478bd9Sstevel@tonic-gate if (strcasecmp(suffix[i].name, end) == 0) { 583*7c478bd9Sstevel@tonic-gate mul = suffix[i].mul; 584*7c478bd9Sstevel@tonic-gate break; 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate if (suffix[i].name == NULL && *end != '\0' || val < 0) 589*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if (mul == 0) { 592*7c478bd9Sstevel@tonic-gate /* 593*7c478bd9Sstevel@tonic-gate * The rate has been specified in frequency-per-second. 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate if (val != 0) 596*7c478bd9Sstevel@tonic-gate val = NANOSEC / val; 597*7c478bd9Sstevel@tonic-gate } else { 598*7c478bd9Sstevel@tonic-gate val *= mul; 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 603*7c478bd9Sstevel@tonic-gate return (0); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* 607*7c478bd9Sstevel@tonic-gate * When setting the strsize option, set the option in the dt_options array 608*7c478bd9Sstevel@tonic-gate * using dt_opt_size() as usual, and then update the definition of the CTF 609*7c478bd9Sstevel@tonic-gate * type for the D intrinsic "string" to be an array of the corresponding size. 610*7c478bd9Sstevel@tonic-gate * If any errors occur, reset dt_options[option] to its previous value. 611*7c478bd9Sstevel@tonic-gate */ 612*7c478bd9Sstevel@tonic-gate static int 613*7c478bd9Sstevel@tonic-gate dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 614*7c478bd9Sstevel@tonic-gate { 615*7c478bd9Sstevel@tonic-gate dtrace_optval_t val = dtp->dt_options[option]; 616*7c478bd9Sstevel@tonic-gate ctf_file_t *fp = DT_STR_CTFP(dtp); 617*7c478bd9Sstevel@tonic-gate ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp)); 618*7c478bd9Sstevel@tonic-gate ctf_arinfo_t r; 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate if (dt_opt_size(dtp, arg, option) != 0) 621*7c478bd9Sstevel@tonic-gate return (-1); /* dt_errno is set for us */ 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate if (dtp->dt_options[option] > UINT_MAX) { 624*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 625*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EOVERFLOW)); 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate if (ctf_array_info(fp, type, &r) == CTF_ERR) { 629*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 630*7c478bd9Sstevel@tonic-gate dtp->dt_ctferr = ctf_errno(fp); 631*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_CTF)); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate r.ctr_nelems = (uint_t)dtp->dt_options[option]; 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate if (ctf_set_array(fp, type, &r) == CTF_ERR || 637*7c478bd9Sstevel@tonic-gate ctf_update(fp) == CTF_ERR) { 638*7c478bd9Sstevel@tonic-gate dtp->dt_options[option] = val; 639*7c478bd9Sstevel@tonic-gate dtp->dt_ctferr = ctf_errno(fp); 640*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_CTF)); 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate return (0); 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate static const struct { 647*7c478bd9Sstevel@tonic-gate const char *dtbp_name; 648*7c478bd9Sstevel@tonic-gate int dtbp_policy; 649*7c478bd9Sstevel@tonic-gate } _dtrace_bufpolicies[] = { 650*7c478bd9Sstevel@tonic-gate { "ring", DTRACEOPT_BUFPOLICY_RING }, 651*7c478bd9Sstevel@tonic-gate { "fill", DTRACEOPT_BUFPOLICY_FILL }, 652*7c478bd9Sstevel@tonic-gate { "switch", DTRACEOPT_BUFPOLICY_SWITCH }, 653*7c478bd9Sstevel@tonic-gate { NULL, 0 } 654*7c478bd9Sstevel@tonic-gate }; 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 657*7c478bd9Sstevel@tonic-gate static int 658*7c478bd9Sstevel@tonic-gate dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 659*7c478bd9Sstevel@tonic-gate { 660*7c478bd9Sstevel@tonic-gate dtrace_optval_t policy = DTRACEOPT_UNSET; 661*7c478bd9Sstevel@tonic-gate int i; 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate if (arg == NULL) 664*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) { 667*7c478bd9Sstevel@tonic-gate if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) { 668*7c478bd9Sstevel@tonic-gate policy = _dtrace_bufpolicies[i].dtbp_policy; 669*7c478bd9Sstevel@tonic-gate break; 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate if (policy == DTRACEOPT_UNSET) 674*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy; 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate return (0); 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate static const struct { 682*7c478bd9Sstevel@tonic-gate const char *dtbr_name; 683*7c478bd9Sstevel@tonic-gate int dtbr_policy; 684*7c478bd9Sstevel@tonic-gate } _dtrace_bufresize[] = { 685*7c478bd9Sstevel@tonic-gate { "auto", DTRACEOPT_BUFRESIZE_AUTO }, 686*7c478bd9Sstevel@tonic-gate { "manual", DTRACEOPT_BUFRESIZE_MANUAL }, 687*7c478bd9Sstevel@tonic-gate { NULL, 0 } 688*7c478bd9Sstevel@tonic-gate }; 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 691*7c478bd9Sstevel@tonic-gate static int 692*7c478bd9Sstevel@tonic-gate dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate dtrace_optval_t policy = DTRACEOPT_UNSET; 695*7c478bd9Sstevel@tonic-gate int i; 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate if (arg == NULL) 698*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) { 701*7c478bd9Sstevel@tonic-gate if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) { 702*7c478bd9Sstevel@tonic-gate policy = _dtrace_bufresize[i].dtbr_policy; 703*7c478bd9Sstevel@tonic-gate break; 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate if (policy == DTRACEOPT_UNSET) 708*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTVAL)); 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate return (0); 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate int 716*7c478bd9Sstevel@tonic-gate dt_options_load(dtrace_hdl_t *dtp) 717*7c478bd9Sstevel@tonic-gate { 718*7c478bd9Sstevel@tonic-gate dof_hdr_t hdr, *dof; 719*7c478bd9Sstevel@tonic-gate dof_sec_t *sec; 720*7c478bd9Sstevel@tonic-gate size_t offs; 721*7c478bd9Sstevel@tonic-gate int i; 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate /* 724*7c478bd9Sstevel@tonic-gate * To load the option values, we need to ask the kernel to provide its 725*7c478bd9Sstevel@tonic-gate * DOF, which we'll sift through to look for OPTDESC sections. 726*7c478bd9Sstevel@tonic-gate */ 727*7c478bd9Sstevel@tonic-gate bzero(&hdr, sizeof (dof_hdr_t)); 728*7c478bd9Sstevel@tonic-gate hdr.dofh_loadsz = sizeof (dof_hdr_t); 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1) 731*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, errno)); 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate if (hdr.dofh_loadsz < sizeof (dof_hdr_t)) 734*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EINVAL)); 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate dof = alloca(hdr.dofh_loadsz); 737*7c478bd9Sstevel@tonic-gate bzero(dof, sizeof (dof_hdr_t)); 738*7c478bd9Sstevel@tonic-gate dof->dofh_loadsz = hdr.dofh_loadsz; 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate for (i = 0; i < DTRACEOPT_MAX; i++) 741*7c478bd9Sstevel@tonic-gate dtp->dt_options[i] = DTRACEOPT_UNSET; 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1) 744*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, errno)); 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate for (i = 0; i < dof->dofh_secnum; i++) { 747*7c478bd9Sstevel@tonic-gate sec = (dof_sec_t *)((uintptr_t)dof + 748*7c478bd9Sstevel@tonic-gate dof->dofh_secoff + i * dof->dofh_secsize); 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate if (sec->dofs_type != DOF_SECT_OPTDESC) 751*7c478bd9Sstevel@tonic-gate continue; 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate break; 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) { 757*7c478bd9Sstevel@tonic-gate dof_optdesc_t *opt = (dof_optdesc_t *)((uintptr_t)dof + 758*7c478bd9Sstevel@tonic-gate sec->dofs_offset + offs); 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate if (opt->dofo_strtab != DOF_SECIDX_NONE) 761*7c478bd9Sstevel@tonic-gate continue; 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate if (opt->dofo_option >= DTRACEOPT_MAX) 764*7c478bd9Sstevel@tonic-gate continue; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate dtp->dt_options[opt->dofo_option] = opt->dofo_value; 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate return (0); 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate typedef struct dt_option { 773*7c478bd9Sstevel@tonic-gate const char *o_name; 774*7c478bd9Sstevel@tonic-gate int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t); 775*7c478bd9Sstevel@tonic-gate uintptr_t o_option; 776*7c478bd9Sstevel@tonic-gate } dt_option_t; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate /* 779*7c478bd9Sstevel@tonic-gate * Compile-time options. 780*7c478bd9Sstevel@tonic-gate */ 781*7c478bd9Sstevel@tonic-gate static const dt_option_t _dtrace_ctoptions[] = { 782*7c478bd9Sstevel@tonic-gate { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU }, 783*7c478bd9Sstevel@tonic-gate { "amin", dt_opt_amin }, 784*7c478bd9Sstevel@tonic-gate { "argref", dt_opt_cflags, DTRACE_C_ARGREF }, 785*7c478bd9Sstevel@tonic-gate { "core", dt_opt_core }, 786*7c478bd9Sstevel@tonic-gate { "cpp", dt_opt_cflags, DTRACE_C_CPP }, 787*7c478bd9Sstevel@tonic-gate { "cpphdrs", dt_opt_cpp_hdrs }, 788*7c478bd9Sstevel@tonic-gate { "cpppath", dt_opt_cpp_path }, 789*7c478bd9Sstevel@tonic-gate { "ctypes", dt_opt_ctypes }, 790*7c478bd9Sstevel@tonic-gate { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG }, 791*7c478bd9Sstevel@tonic-gate { "dtypes", dt_opt_dtypes }, 792*7c478bd9Sstevel@tonic-gate { "debug", dt_opt_debug }, 793*7c478bd9Sstevel@tonic-gate { "define", dt_opt_cpp_opts, (uintptr_t)"-D" }, 794*7c478bd9Sstevel@tonic-gate { "empty", dt_opt_cflags, DTRACE_C_EMPTY }, 795*7c478bd9Sstevel@tonic-gate { "errtags", dt_opt_cflags, DTRACE_C_ETAGS }, 796*7c478bd9Sstevel@tonic-gate { "evaltime", dt_opt_evaltime }, 797*7c478bd9Sstevel@tonic-gate { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" }, 798*7c478bd9Sstevel@tonic-gate { "iregs", dt_opt_iregs }, 799*7c478bd9Sstevel@tonic-gate { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF }, 800*7c478bd9Sstevel@tonic-gate { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF }, 801*7c478bd9Sstevel@tonic-gate { "lazyload", dt_opt_lazyload }, 802*7c478bd9Sstevel@tonic-gate { "ldpath", dt_opt_ld_path }, 803*7c478bd9Sstevel@tonic-gate { "libdir", dt_opt_libdir }, 804*7c478bd9Sstevel@tonic-gate { "linkmode", dt_opt_linkmode }, 805*7c478bd9Sstevel@tonic-gate { "linktype", dt_opt_linktype }, 806*7c478bd9Sstevel@tonic-gate { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS }, 807*7c478bd9Sstevel@tonic-gate { "pgmax", dt_opt_pgmax }, 808*7c478bd9Sstevel@tonic-gate { "pspec", dt_opt_cflags, DTRACE_C_PSPEC }, 809*7c478bd9Sstevel@tonic-gate { "stdc", dt_opt_stdc }, 810*7c478bd9Sstevel@tonic-gate { "strip", dt_opt_dflags, DTRACE_D_STRIP }, 811*7c478bd9Sstevel@tonic-gate { "syslibdir", dt_opt_syslibdir }, 812*7c478bd9Sstevel@tonic-gate { "tree", dt_opt_tree }, 813*7c478bd9Sstevel@tonic-gate { "tregs", dt_opt_tregs }, 814*7c478bd9Sstevel@tonic-gate { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF }, 815*7c478bd9Sstevel@tonic-gate { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" }, 816*7c478bd9Sstevel@tonic-gate { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF }, 817*7c478bd9Sstevel@tonic-gate { "verbose", dt_opt_cflags, DTRACE_C_DIFV }, 818*7c478bd9Sstevel@tonic-gate { "version", dt_opt_version }, 819*7c478bd9Sstevel@tonic-gate { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS }, 820*7c478bd9Sstevel@tonic-gate { NULL } 821*7c478bd9Sstevel@tonic-gate }; 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate /* 824*7c478bd9Sstevel@tonic-gate * Run-time options. 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate static const dt_option_t _dtrace_rtoptions[] = { 827*7c478bd9Sstevel@tonic-gate { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE }, 828*7c478bd9Sstevel@tonic-gate { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE }, 829*7c478bd9Sstevel@tonic-gate { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE }, 830*7c478bd9Sstevel@tonic-gate { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY }, 831*7c478bd9Sstevel@tonic-gate { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE }, 832*7c478bd9Sstevel@tonic-gate { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE }, 833*7c478bd9Sstevel@tonic-gate { "cpu", dt_opt_runtime, DTRACEOPT_CPU }, 834*7c478bd9Sstevel@tonic-gate { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE }, 835*7c478bd9Sstevel@tonic-gate { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE }, 836*7c478bd9Sstevel@tonic-gate { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT }, 837*7c478bd9Sstevel@tonic-gate { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON }, 838*7c478bd9Sstevel@tonic-gate { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES }, 839*7c478bd9Sstevel@tonic-gate { "jstackstrsize", dt_opt_runtime, DTRACEOPT_JSTACKSTRSIZE }, 840*7c478bd9Sstevel@tonic-gate { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC }, 841*7c478bd9Sstevel@tonic-gate { "quiet", dt_opt_runtime, DTRACEOPT_QUIET }, 842*7c478bd9Sstevel@tonic-gate { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES }, 843*7c478bd9Sstevel@tonic-gate { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE }, 844*7c478bd9Sstevel@tonic-gate { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES }, 845*7c478bd9Sstevel@tonic-gate { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT }, 846*7c478bd9Sstevel@tonic-gate { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE }, 847*7c478bd9Sstevel@tonic-gate { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE }, 848*7c478bd9Sstevel@tonic-gate { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE }, 849*7c478bd9Sstevel@tonic-gate { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES }, 850*7c478bd9Sstevel@tonic-gate { NULL } 851*7c478bd9Sstevel@tonic-gate }; 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate int 854*7c478bd9Sstevel@tonic-gate dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val) 855*7c478bd9Sstevel@tonic-gate { 856*7c478bd9Sstevel@tonic-gate const dt_option_t *op; 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate if (opt == NULL) 859*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EINVAL)); 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate /* 862*7c478bd9Sstevel@tonic-gate * We only need to search the run-time options -- it's not legal 863*7c478bd9Sstevel@tonic-gate * to get the values of compile-time options. 864*7c478bd9Sstevel@tonic-gate */ 865*7c478bd9Sstevel@tonic-gate for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 866*7c478bd9Sstevel@tonic-gate if (strcmp(op->o_name, opt) == 0) { 867*7c478bd9Sstevel@tonic-gate *val = dtp->dt_options[op->o_option]; 868*7c478bd9Sstevel@tonic-gate return (0); 869*7c478bd9Sstevel@tonic-gate } 870*7c478bd9Sstevel@tonic-gate } 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTNAME)); 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate int 876*7c478bd9Sstevel@tonic-gate dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val) 877*7c478bd9Sstevel@tonic-gate { 878*7c478bd9Sstevel@tonic-gate const dt_option_t *op; 879*7c478bd9Sstevel@tonic-gate 880*7c478bd9Sstevel@tonic-gate if (opt == NULL) 881*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EINVAL)); 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate for (op = _dtrace_ctoptions; op->o_name != NULL; op++) { 884*7c478bd9Sstevel@tonic-gate if (strcmp(op->o_name, opt) == 0) 885*7c478bd9Sstevel@tonic-gate return (op->o_func(dtp, val, op->o_option)); 886*7c478bd9Sstevel@tonic-gate } 887*7c478bd9Sstevel@tonic-gate 888*7c478bd9Sstevel@tonic-gate for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 889*7c478bd9Sstevel@tonic-gate if (strcmp(op->o_name, opt) == 0) { 890*7c478bd9Sstevel@tonic-gate /* 891*7c478bd9Sstevel@tonic-gate * Currently, no run-time option may be set while 892*7c478bd9Sstevel@tonic-gate * tracing is active. 893*7c478bd9Sstevel@tonic-gate */ 894*7c478bd9Sstevel@tonic-gate if (dtp->dt_active) 895*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_ACTIVE)); 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate return (op->o_func(dtp, val, op->o_option)); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_BADOPTNAME)); 902*7c478bd9Sstevel@tonic-gate } 903