1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef _SYS_DTRACE_H 28*0Sstevel@tonic-gate #define _SYS_DTRACE_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #ifdef __cplusplus 33*0Sstevel@tonic-gate extern "C" { 34*0Sstevel@tonic-gate #endif 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate /* 37*0Sstevel@tonic-gate * DTrace Dynamic Tracing Software: Kernel Interfaces 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * Note: The contents of this file are private to the implementation of the 40*0Sstevel@tonic-gate * Solaris system and DTrace subsystem and are subject to change at any time 41*0Sstevel@tonic-gate * without notice. Applications and drivers using these interfaces will fail 42*0Sstevel@tonic-gate * to run on future releases. These interfaces should not be used for any 43*0Sstevel@tonic-gate * purpose except those expressly outlined in dtrace(7D) and libdtrace(3LIB). 44*0Sstevel@tonic-gate * Please refer to the "Solaris Dynamic Tracing Guide" for more information. 45*0Sstevel@tonic-gate */ 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #ifndef _ASM 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate #include <sys/types.h> 50*0Sstevel@tonic-gate #include <sys/modctl.h> 51*0Sstevel@tonic-gate #include <sys/processor.h> 52*0Sstevel@tonic-gate #include <sys/systm.h> 53*0Sstevel@tonic-gate #include <sys/ctf_api.h> 54*0Sstevel@tonic-gate #include <sys/cyclic.h> 55*0Sstevel@tonic-gate #include <sys/int_limits.h> 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate /* 58*0Sstevel@tonic-gate * DTrace Universal Constants and Typedefs 59*0Sstevel@tonic-gate */ 60*0Sstevel@tonic-gate #define DTRACE_CPUALL -1 /* all CPUs */ 61*0Sstevel@tonic-gate #define DTRACE_IDNONE 0 /* invalid probe identifier */ 62*0Sstevel@tonic-gate #define DTRACE_EPIDNONE 0 /* invalid enabled probe identifier */ 63*0Sstevel@tonic-gate #define DTRACE_AGGIDNONE 0 /* invalid aggregation identifier */ 64*0Sstevel@tonic-gate #define DTRACE_CACHEIDNONE 0 /* invalid predicate cache */ 65*0Sstevel@tonic-gate #define DTRACE_PROVNONE 0 /* invalid provider identifier */ 66*0Sstevel@tonic-gate #define DTRACE_METAPROVNONE 0 /* invalid meta-provider identifier */ 67*0Sstevel@tonic-gate #define DTRACE_ARGNONE -1 /* invalid argument index */ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #define DTRACE_PROVNAMELEN 64 70*0Sstevel@tonic-gate #define DTRACE_MODNAMELEN 64 71*0Sstevel@tonic-gate #define DTRACE_FUNCNAMELEN 128 72*0Sstevel@tonic-gate #define DTRACE_NAMELEN 64 73*0Sstevel@tonic-gate #define DTRACE_FULLNAMELEN (DTRACE_PROVNAMELEN + DTRACE_MODNAMELEN + \ 74*0Sstevel@tonic-gate DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 4) 75*0Sstevel@tonic-gate #define DTRACE_ARGTYPELEN 128 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate typedef uint32_t dtrace_id_t; /* probe identifier */ 78*0Sstevel@tonic-gate typedef uint32_t dtrace_epid_t; /* enabled probe identifier */ 79*0Sstevel@tonic-gate typedef uint32_t dtrace_aggid_t; /* aggregation identifier */ 80*0Sstevel@tonic-gate typedef uint16_t dtrace_actkind_t; /* action kind */ 81*0Sstevel@tonic-gate typedef int64_t dtrace_optval_t; /* option value */ 82*0Sstevel@tonic-gate typedef uint32_t dtrace_cacheid_t; /* predicate cache identifier */ 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate typedef enum dtrace_probespec { 85*0Sstevel@tonic-gate DTRACE_PROBESPEC_NONE = -1, 86*0Sstevel@tonic-gate DTRACE_PROBESPEC_PROVIDER = 0, 87*0Sstevel@tonic-gate DTRACE_PROBESPEC_MOD, 88*0Sstevel@tonic-gate DTRACE_PROBESPEC_FUNC, 89*0Sstevel@tonic-gate DTRACE_PROBESPEC_NAME 90*0Sstevel@tonic-gate } dtrace_probespec_t; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate /* 93*0Sstevel@tonic-gate * DTrace Intermediate Format (DIF) 94*0Sstevel@tonic-gate * 95*0Sstevel@tonic-gate * The following definitions describe the DTrace Intermediate Format (DIF), a 96*0Sstevel@tonic-gate * a RISC-like instruction set and program encoding used to represent 97*0Sstevel@tonic-gate * predicates and actions that can be bound to DTrace probes. The constants 98*0Sstevel@tonic-gate * below defining the number of available registers are suggested minimums; the 99*0Sstevel@tonic-gate * compiler should use DTRACEIOC_CONF to dynamically obtain the number of 100*0Sstevel@tonic-gate * registers provided by the current DTrace implementation. 101*0Sstevel@tonic-gate */ 102*0Sstevel@tonic-gate #define DIF_VERSION_1 1 /* DIF version 1: Solaris 10 Beta */ 103*0Sstevel@tonic-gate #define DIF_VERSION_2 2 /* DIF version 2: Solaris 10 FCS */ 104*0Sstevel@tonic-gate #define DIF_VERSION DIF_VERSION_2 /* latest DIF instruction set version */ 105*0Sstevel@tonic-gate #define DIF_DIR_NREGS 8 /* number of DIF integer registers */ 106*0Sstevel@tonic-gate #define DIF_DTR_NREGS 8 /* number of DIF tuple registers */ 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate #define DIF_OP_OR 1 /* or r1, r2, rd */ 109*0Sstevel@tonic-gate #define DIF_OP_XOR 2 /* xor r1, r2, rd */ 110*0Sstevel@tonic-gate #define DIF_OP_AND 3 /* and r1, r2, rd */ 111*0Sstevel@tonic-gate #define DIF_OP_SLL 4 /* sll r1, r2, rd */ 112*0Sstevel@tonic-gate #define DIF_OP_SRL 5 /* srl r1, r2, rd */ 113*0Sstevel@tonic-gate #define DIF_OP_SUB 6 /* sub r1, r2, rd */ 114*0Sstevel@tonic-gate #define DIF_OP_ADD 7 /* add r1, r2, rd */ 115*0Sstevel@tonic-gate #define DIF_OP_MUL 8 /* mul r1, r2, rd */ 116*0Sstevel@tonic-gate #define DIF_OP_SDIV 9 /* sdiv r1, r2, rd */ 117*0Sstevel@tonic-gate #define DIF_OP_UDIV 10 /* udiv r1, r2, rd */ 118*0Sstevel@tonic-gate #define DIF_OP_SREM 11 /* srem r1, r2, rd */ 119*0Sstevel@tonic-gate #define DIF_OP_UREM 12 /* urem r1, r2, rd */ 120*0Sstevel@tonic-gate #define DIF_OP_NOT 13 /* not r1, rd */ 121*0Sstevel@tonic-gate #define DIF_OP_MOV 14 /* mov r1, rd */ 122*0Sstevel@tonic-gate #define DIF_OP_CMP 15 /* cmp r1, r2 */ 123*0Sstevel@tonic-gate #define DIF_OP_TST 16 /* tst r1 */ 124*0Sstevel@tonic-gate #define DIF_OP_BA 17 /* ba label */ 125*0Sstevel@tonic-gate #define DIF_OP_BE 18 /* be label */ 126*0Sstevel@tonic-gate #define DIF_OP_BNE 19 /* bne label */ 127*0Sstevel@tonic-gate #define DIF_OP_BG 20 /* bg label */ 128*0Sstevel@tonic-gate #define DIF_OP_BGU 21 /* bgu label */ 129*0Sstevel@tonic-gate #define DIF_OP_BGE 22 /* bge label */ 130*0Sstevel@tonic-gate #define DIF_OP_BGEU 23 /* bgeu label */ 131*0Sstevel@tonic-gate #define DIF_OP_BL 24 /* bl label */ 132*0Sstevel@tonic-gate #define DIF_OP_BLU 25 /* blu label */ 133*0Sstevel@tonic-gate #define DIF_OP_BLE 26 /* ble label */ 134*0Sstevel@tonic-gate #define DIF_OP_BLEU 27 /* bleu label */ 135*0Sstevel@tonic-gate #define DIF_OP_LDSB 28 /* ldsb [r1], rd */ 136*0Sstevel@tonic-gate #define DIF_OP_LDSH 29 /* ldsh [r1], rd */ 137*0Sstevel@tonic-gate #define DIF_OP_LDSW 30 /* ldsw [r1], rd */ 138*0Sstevel@tonic-gate #define DIF_OP_LDUB 31 /* ldub [r1], rd */ 139*0Sstevel@tonic-gate #define DIF_OP_LDUH 32 /* lduh [r1], rd */ 140*0Sstevel@tonic-gate #define DIF_OP_LDUW 33 /* lduw [r1], rd */ 141*0Sstevel@tonic-gate #define DIF_OP_LDX 34 /* ldx [r1], rd */ 142*0Sstevel@tonic-gate #define DIF_OP_RET 35 /* ret rd */ 143*0Sstevel@tonic-gate #define DIF_OP_NOP 36 /* nop */ 144*0Sstevel@tonic-gate #define DIF_OP_SETX 37 /* setx intindex, rd */ 145*0Sstevel@tonic-gate #define DIF_OP_SETS 38 /* sets strindex, rd */ 146*0Sstevel@tonic-gate #define DIF_OP_SCMP 39 /* scmp r1, r2 */ 147*0Sstevel@tonic-gate #define DIF_OP_LDGA 40 /* ldga var, ri, rd */ 148*0Sstevel@tonic-gate #define DIF_OP_LDGS 41 /* ldgs var, rd */ 149*0Sstevel@tonic-gate #define DIF_OP_STGS 42 /* stgs var, rs */ 150*0Sstevel@tonic-gate #define DIF_OP_LDTA 43 /* ldta var, ri, rd */ 151*0Sstevel@tonic-gate #define DIF_OP_LDTS 44 /* ldts var, rd */ 152*0Sstevel@tonic-gate #define DIF_OP_STTS 45 /* stts var, rs */ 153*0Sstevel@tonic-gate #define DIF_OP_SRA 46 /* sra r1, r2, rd */ 154*0Sstevel@tonic-gate #define DIF_OP_CALL 47 /* call subr, rd */ 155*0Sstevel@tonic-gate #define DIF_OP_PUSHTR 48 /* pushtr type, rs, rr */ 156*0Sstevel@tonic-gate #define DIF_OP_PUSHTV 49 /* pushtv type, rs, rv */ 157*0Sstevel@tonic-gate #define DIF_OP_POPTS 50 /* popts */ 158*0Sstevel@tonic-gate #define DIF_OP_FLUSHTS 51 /* flushts */ 159*0Sstevel@tonic-gate #define DIF_OP_LDGAA 52 /* ldgaa var, rd */ 160*0Sstevel@tonic-gate #define DIF_OP_LDTAA 53 /* ldtaa var, rd */ 161*0Sstevel@tonic-gate #define DIF_OP_STGAA 54 /* stgaa var, rs */ 162*0Sstevel@tonic-gate #define DIF_OP_STTAA 55 /* sttaa var, rs */ 163*0Sstevel@tonic-gate #define DIF_OP_LDLS 56 /* ldls var, rd */ 164*0Sstevel@tonic-gate #define DIF_OP_STLS 57 /* stls var, rs */ 165*0Sstevel@tonic-gate #define DIF_OP_ALLOCS 58 /* allocs r1, rd */ 166*0Sstevel@tonic-gate #define DIF_OP_COPYS 59 /* copys r1, r2, rd */ 167*0Sstevel@tonic-gate #define DIF_OP_STB 60 /* stb r1, [rd] */ 168*0Sstevel@tonic-gate #define DIF_OP_STH 61 /* sth r1, [rd] */ 169*0Sstevel@tonic-gate #define DIF_OP_STW 62 /* stw r1, [rd] */ 170*0Sstevel@tonic-gate #define DIF_OP_STX 63 /* stx r1, [rd] */ 171*0Sstevel@tonic-gate #define DIF_OP_ULDSB 64 /* uldsb [r1], rd */ 172*0Sstevel@tonic-gate #define DIF_OP_ULDSH 65 /* uldsh [r1], rd */ 173*0Sstevel@tonic-gate #define DIF_OP_ULDSW 66 /* uldsw [r1], rd */ 174*0Sstevel@tonic-gate #define DIF_OP_ULDUB 67 /* uldub [r1], rd */ 175*0Sstevel@tonic-gate #define DIF_OP_ULDUH 68 /* ulduh [r1], rd */ 176*0Sstevel@tonic-gate #define DIF_OP_ULDUW 69 /* ulduw [r1], rd */ 177*0Sstevel@tonic-gate #define DIF_OP_ULDX 70 /* uldx [r1], rd */ 178*0Sstevel@tonic-gate #define DIF_OP_RLDSB 71 /* rldsb [r1], rd */ 179*0Sstevel@tonic-gate #define DIF_OP_RLDSH 72 /* rldsh [r1], rd */ 180*0Sstevel@tonic-gate #define DIF_OP_RLDSW 73 /* rldsw [r1], rd */ 181*0Sstevel@tonic-gate #define DIF_OP_RLDUB 74 /* rldub [r1], rd */ 182*0Sstevel@tonic-gate #define DIF_OP_RLDUH 75 /* rlduh [r1], rd */ 183*0Sstevel@tonic-gate #define DIF_OP_RLDUW 76 /* rlduw [r1], rd */ 184*0Sstevel@tonic-gate #define DIF_OP_RLDX 77 /* rldx [r1], rd */ 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate #define DIF_INTOFF_MAX 0xffff /* highest integer table offset */ 187*0Sstevel@tonic-gate #define DIF_STROFF_MAX 0xffff /* highest string table offset */ 188*0Sstevel@tonic-gate #define DIF_REGISTER_MAX 0xff /* highest register number */ 189*0Sstevel@tonic-gate #define DIF_VARIABLE_MAX 0xffff /* highest variable identifier */ 190*0Sstevel@tonic-gate #define DIF_SUBROUTINE_MAX 0xffff /* highest subroutine code */ 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate #define DIF_VAR_ARRAY_MIN 0x0000 /* lowest numbered array variable */ 193*0Sstevel@tonic-gate #define DIF_VAR_ARRAY_UBASE 0x0080 /* lowest user-defined array */ 194*0Sstevel@tonic-gate #define DIF_VAR_ARRAY_MAX 0x00ff /* highest numbered array variable */ 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate #define DIF_VAR_OTHER_MIN 0x0100 /* lowest numbered scalar or assc */ 197*0Sstevel@tonic-gate #define DIF_VAR_OTHER_UBASE 0x0500 /* lowest user-defined scalar or assc */ 198*0Sstevel@tonic-gate #define DIF_VAR_OTHER_MAX 0xffff /* highest numbered scalar or assc */ 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate #define DIF_VAR_ARGS 0x0000 /* arguments array */ 201*0Sstevel@tonic-gate #define DIF_VAR_REGS 0x0001 /* registers array */ 202*0Sstevel@tonic-gate #define DIF_VAR_UREGS 0x0002 /* user registers array */ 203*0Sstevel@tonic-gate #define DIF_VAR_CURTHREAD 0x0100 /* thread pointer */ 204*0Sstevel@tonic-gate #define DIF_VAR_TIMESTAMP 0x0101 /* timestamp */ 205*0Sstevel@tonic-gate #define DIF_VAR_VTIMESTAMP 0x0102 /* virtual timestamp */ 206*0Sstevel@tonic-gate #define DIF_VAR_IPL 0x0103 /* interrupt priority level */ 207*0Sstevel@tonic-gate #define DIF_VAR_EPID 0x0104 /* enabled probe ID */ 208*0Sstevel@tonic-gate #define DIF_VAR_ID 0x0105 /* probe ID */ 209*0Sstevel@tonic-gate #define DIF_VAR_ARG0 0x0106 /* first argument */ 210*0Sstevel@tonic-gate #define DIF_VAR_ARG1 0x0107 /* second argument */ 211*0Sstevel@tonic-gate #define DIF_VAR_ARG2 0x0108 /* third argument */ 212*0Sstevel@tonic-gate #define DIF_VAR_ARG3 0x0109 /* fourth argument */ 213*0Sstevel@tonic-gate #define DIF_VAR_ARG4 0x010a /* fifth argument */ 214*0Sstevel@tonic-gate #define DIF_VAR_ARG5 0x010b /* sixth argument */ 215*0Sstevel@tonic-gate #define DIF_VAR_ARG6 0x010c /* seventh argument */ 216*0Sstevel@tonic-gate #define DIF_VAR_ARG7 0x010d /* eighth argument */ 217*0Sstevel@tonic-gate #define DIF_VAR_ARG8 0x010e /* ninth argument */ 218*0Sstevel@tonic-gate #define DIF_VAR_ARG9 0x010f /* tenth argument */ 219*0Sstevel@tonic-gate #define DIF_VAR_STACKDEPTH 0x0110 /* stack depth */ 220*0Sstevel@tonic-gate #define DIF_VAR_CALLER 0x0111 /* caller */ 221*0Sstevel@tonic-gate #define DIF_VAR_PROBEPROV 0x0112 /* probe provider */ 222*0Sstevel@tonic-gate #define DIF_VAR_PROBEMOD 0x0113 /* probe module */ 223*0Sstevel@tonic-gate #define DIF_VAR_PROBEFUNC 0x0114 /* probe function */ 224*0Sstevel@tonic-gate #define DIF_VAR_PROBENAME 0x0115 /* probe name */ 225*0Sstevel@tonic-gate #define DIF_VAR_PID 0x0116 /* process ID */ 226*0Sstevel@tonic-gate #define DIF_VAR_TID 0x0117 /* (per-process) thread ID */ 227*0Sstevel@tonic-gate #define DIF_VAR_EXECNAME 0x0118 /* name of executable */ 228*0Sstevel@tonic-gate #define DIF_VAR_ZONENAME 0x0119 /* zone name associated with process */ 229*0Sstevel@tonic-gate #define DIF_VAR_WALLTIMESTAMP 0x011a /* wall-clock timestamp */ 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate #define DIF_SUBR_RAND 0 232*0Sstevel@tonic-gate #define DIF_SUBR_MUTEX_OWNED 1 233*0Sstevel@tonic-gate #define DIF_SUBR_MUTEX_OWNER 2 234*0Sstevel@tonic-gate #define DIF_SUBR_MUTEX_TYPE_ADAPTIVE 3 235*0Sstevel@tonic-gate #define DIF_SUBR_MUTEX_TYPE_SPIN 4 236*0Sstevel@tonic-gate #define DIF_SUBR_RW_READ_HELD 5 237*0Sstevel@tonic-gate #define DIF_SUBR_RW_WRITE_HELD 6 238*0Sstevel@tonic-gate #define DIF_SUBR_RW_ISWRITER 7 239*0Sstevel@tonic-gate #define DIF_SUBR_COPYIN 8 240*0Sstevel@tonic-gate #define DIF_SUBR_COPYINSTR 9 241*0Sstevel@tonic-gate #define DIF_SUBR_SPECULATION 10 242*0Sstevel@tonic-gate #define DIF_SUBR_PROGENYOF 11 243*0Sstevel@tonic-gate #define DIF_SUBR_STRLEN 12 244*0Sstevel@tonic-gate #define DIF_SUBR_COPYOUT 13 245*0Sstevel@tonic-gate #define DIF_SUBR_COPYOUTSTR 14 246*0Sstevel@tonic-gate #define DIF_SUBR_ALLOCA 15 247*0Sstevel@tonic-gate #define DIF_SUBR_BCOPY 16 248*0Sstevel@tonic-gate #define DIF_SUBR_COPYINTO 17 249*0Sstevel@tonic-gate #define DIF_SUBR_MSGDSIZE 18 250*0Sstevel@tonic-gate #define DIF_SUBR_MSGSIZE 19 251*0Sstevel@tonic-gate #define DIF_SUBR_GETMAJOR 20 252*0Sstevel@tonic-gate #define DIF_SUBR_GETMINOR 21 253*0Sstevel@tonic-gate #define DIF_SUBR_DDI_PATHNAME 22 254*0Sstevel@tonic-gate #define DIF_SUBR_STRJOIN 23 255*0Sstevel@tonic-gate #define DIF_SUBR_LLTOSTR 24 256*0Sstevel@tonic-gate #define DIF_SUBR_BASENAME 25 257*0Sstevel@tonic-gate #define DIF_SUBR_DIRNAME 26 258*0Sstevel@tonic-gate #define DIF_SUBR_CLEANPATH 27 259*0Sstevel@tonic-gate #define DIF_SUBR_STRCHR 28 260*0Sstevel@tonic-gate #define DIF_SUBR_STRRCHR 29 261*0Sstevel@tonic-gate #define DIF_SUBR_STRSTR 30 262*0Sstevel@tonic-gate #define DIF_SUBR_STRTOK 31 263*0Sstevel@tonic-gate #define DIF_SUBR_SUBSTR 32 264*0Sstevel@tonic-gate #define DIF_SUBR_INDEX 33 265*0Sstevel@tonic-gate #define DIF_SUBR_RINDEX 34 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate #define DIF_SUBR_MAX 34 /* max subroutine value */ 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate typedef uint32_t dif_instr_t; 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate #define DIF_INSTR_OP(i) (((i) >> 24) & 0xff) 272*0Sstevel@tonic-gate #define DIF_INSTR_R1(i) (((i) >> 16) & 0xff) 273*0Sstevel@tonic-gate #define DIF_INSTR_R2(i) (((i) >> 8) & 0xff) 274*0Sstevel@tonic-gate #define DIF_INSTR_RD(i) ((i) & 0xff) 275*0Sstevel@tonic-gate #define DIF_INSTR_RS(i) ((i) & 0xff) 276*0Sstevel@tonic-gate #define DIF_INSTR_LABEL(i) ((i) & 0xffffff) 277*0Sstevel@tonic-gate #define DIF_INSTR_VAR(i) (((i) >> 8) & 0xffff) 278*0Sstevel@tonic-gate #define DIF_INSTR_INTEGER(i) (((i) >> 8) & 0xffff) 279*0Sstevel@tonic-gate #define DIF_INSTR_STRING(i) (((i) >> 8) & 0xffff) 280*0Sstevel@tonic-gate #define DIF_INSTR_SUBR(i) (((i) >> 8) & 0xffff) 281*0Sstevel@tonic-gate #define DIF_INSTR_TYPE(i) (((i) >> 16) & 0xff) 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate #define DIF_INSTR_FMT(op, r1, r2, d) \ 284*0Sstevel@tonic-gate (((op) << 24) | ((r1) << 16) | ((r2) << 8) | (d)) 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate #define DIF_INSTR_NOT(r1, d) (DIF_INSTR_FMT(DIF_OP_NOT, r1, 0, d)) 287*0Sstevel@tonic-gate #define DIF_INSTR_MOV(r1, d) (DIF_INSTR_FMT(DIF_OP_MOV, r1, 0, d)) 288*0Sstevel@tonic-gate #define DIF_INSTR_CMP(op, r1, r2) (DIF_INSTR_FMT(op, r1, r2, 0)) 289*0Sstevel@tonic-gate #define DIF_INSTR_TST(r1) (DIF_INSTR_FMT(DIF_OP_TST, r1, 0, 0)) 290*0Sstevel@tonic-gate #define DIF_INSTR_BRANCH(op, label) (((op) << 24) | (label)) 291*0Sstevel@tonic-gate #define DIF_INSTR_LOAD(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) 292*0Sstevel@tonic-gate #define DIF_INSTR_STORE(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) 293*0Sstevel@tonic-gate #define DIF_INSTR_SETX(i, d) ((DIF_OP_SETX << 24) | ((i) << 8) | (d)) 294*0Sstevel@tonic-gate #define DIF_INSTR_SETS(s, d) ((DIF_OP_SETS << 24) | ((s) << 8) | (d)) 295*0Sstevel@tonic-gate #define DIF_INSTR_RET(d) (DIF_INSTR_FMT(DIF_OP_RET, 0, 0, d)) 296*0Sstevel@tonic-gate #define DIF_INSTR_NOP (DIF_OP_NOP << 24) 297*0Sstevel@tonic-gate #define DIF_INSTR_LDA(op, v, r, d) (DIF_INSTR_FMT(op, v, r, d)) 298*0Sstevel@tonic-gate #define DIF_INSTR_LDV(op, v, d) (((op) << 24) | ((v) << 8) | (d)) 299*0Sstevel@tonic-gate #define DIF_INSTR_STV(op, v, rs) (((op) << 24) | ((v) << 8) | (rs)) 300*0Sstevel@tonic-gate #define DIF_INSTR_CALL(s, d) ((DIF_OP_CALL << 24) | ((s) << 8) | (d)) 301*0Sstevel@tonic-gate #define DIF_INSTR_PUSHTS(op, t, r2, rs) (DIF_INSTR_FMT(op, t, r2, rs)) 302*0Sstevel@tonic-gate #define DIF_INSTR_POPTS (DIF_OP_POPTS << 24) 303*0Sstevel@tonic-gate #define DIF_INSTR_FLUSHTS (DIF_OP_FLUSHTS << 24) 304*0Sstevel@tonic-gate #define DIF_INSTR_ALLOCS(r1, d) (DIF_INSTR_FMT(DIF_OP_ALLOCS, r1, 0, d)) 305*0Sstevel@tonic-gate #define DIF_INSTR_COPYS(r1, r2, d) (DIF_INSTR_FMT(DIF_OP_COPYS, r1, r2, d)) 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate #define DIF_REG_R0 0 /* %r0 is always set to zero */ 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* 310*0Sstevel@tonic-gate * A DTrace Intermediate Format Type (DIF Type) is used to represent the types 311*0Sstevel@tonic-gate * of variables, function and associative array arguments, and the return type 312*0Sstevel@tonic-gate * for each DIF object (shown below). It contains a description of the type, 313*0Sstevel@tonic-gate * its size in bytes, and a module identifier. 314*0Sstevel@tonic-gate */ 315*0Sstevel@tonic-gate typedef struct dtrace_diftype { 316*0Sstevel@tonic-gate uint8_t dtdt_kind; /* type kind (see below) */ 317*0Sstevel@tonic-gate uint8_t dtdt_ckind; /* type kind in CTF */ 318*0Sstevel@tonic-gate uint8_t dtdt_flags; /* type flags (see below) */ 319*0Sstevel@tonic-gate uint8_t dtdt_pad; /* reserved for future use */ 320*0Sstevel@tonic-gate uint32_t dtdt_size; /* type size in bytes (unless string) */ 321*0Sstevel@tonic-gate } dtrace_diftype_t; 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate #define DIF_TYPE_CTF 0 /* type is a CTF type */ 324*0Sstevel@tonic-gate #define DIF_TYPE_STRING 1 /* type is a D string */ 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate #define DIF_TF_BYREF 0x1 /* type is passed by reference */ 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate /* 329*0Sstevel@tonic-gate * A DTrace Intermediate Format variable record is used to describe each of the 330*0Sstevel@tonic-gate * variables referenced by a given DIF object. It contains an integer variable 331*0Sstevel@tonic-gate * identifier along with variable scope and properties, as shown below. The 332*0Sstevel@tonic-gate * size of this structure must be sizeof (int) aligned. 333*0Sstevel@tonic-gate */ 334*0Sstevel@tonic-gate typedef struct dtrace_difv { 335*0Sstevel@tonic-gate uint32_t dtdv_name; /* variable name index in dtdo_strtab */ 336*0Sstevel@tonic-gate uint32_t dtdv_id; /* variable reference identifier */ 337*0Sstevel@tonic-gate uint8_t dtdv_kind; /* variable kind (see below) */ 338*0Sstevel@tonic-gate uint8_t dtdv_scope; /* variable scope (see below) */ 339*0Sstevel@tonic-gate uint16_t dtdv_flags; /* variable flags (see below) */ 340*0Sstevel@tonic-gate dtrace_diftype_t dtdv_type; /* variable type (see above) */ 341*0Sstevel@tonic-gate } dtrace_difv_t; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate #define DIFV_KIND_ARRAY 0 /* variable is an array of quantities */ 344*0Sstevel@tonic-gate #define DIFV_KIND_SCALAR 1 /* variable is a scalar quantity */ 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate #define DIFV_SCOPE_GLOBAL 0 /* variable has global scope */ 347*0Sstevel@tonic-gate #define DIFV_SCOPE_THREAD 1 /* variable has thread scope */ 348*0Sstevel@tonic-gate #define DIFV_SCOPE_LOCAL 2 /* variable has local scope */ 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate #define DIFV_F_REF 0x1 /* variable is referenced by DIFO */ 351*0Sstevel@tonic-gate #define DIFV_F_MOD 0x2 /* variable is written by DIFO */ 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate /* 354*0Sstevel@tonic-gate * DTrace Actions 355*0Sstevel@tonic-gate * 356*0Sstevel@tonic-gate * The upper byte determines the class of the action; the low bytes determines 357*0Sstevel@tonic-gate * the specific action within that class. The classes of actions are as 358*0Sstevel@tonic-gate * follows: 359*0Sstevel@tonic-gate * 360*0Sstevel@tonic-gate * [ no class ] <= May record process- or kernel-related data 361*0Sstevel@tonic-gate * DTRACEACT_PROC <= Only records process-related data 362*0Sstevel@tonic-gate * DTRACEACT_PROC_DESTRUCTIVE <= Potentially destructive to processes 363*0Sstevel@tonic-gate * DTRACEACT_KERNEL <= Only records kernel-related data 364*0Sstevel@tonic-gate * DTRACEACT_KERNEL_DESTRUCTIVE <= Potentially destructive to the kernel 365*0Sstevel@tonic-gate * DTRACEACT_SPECULATIVE <= Speculation-related action 366*0Sstevel@tonic-gate * DTRACEACT_AGGREGATION <= Aggregating action 367*0Sstevel@tonic-gate */ 368*0Sstevel@tonic-gate #define DTRACEACT_NONE 0 /* no action */ 369*0Sstevel@tonic-gate #define DTRACEACT_DIFEXPR 1 /* action is DIF expression */ 370*0Sstevel@tonic-gate #define DTRACEACT_EXIT 2 /* exit() action */ 371*0Sstevel@tonic-gate #define DTRACEACT_PRINTF 3 /* printf() action */ 372*0Sstevel@tonic-gate #define DTRACEACT_PRINTA 4 /* printa() action */ 373*0Sstevel@tonic-gate #define DTRACEACT_LIBACT 5 /* library-controlled action */ 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate #define DTRACEACT_PROC 0x0100 376*0Sstevel@tonic-gate #define DTRACEACT_USTACK (DTRACEACT_PROC + 1) 377*0Sstevel@tonic-gate #define DTRACEACT_JSTACK (DTRACEACT_PROC + 2) 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate #define DTRACEACT_PROC_DESTRUCTIVE 0x0200 380*0Sstevel@tonic-gate #define DTRACEACT_STOP (DTRACEACT_PROC_DESTRUCTIVE + 1) 381*0Sstevel@tonic-gate #define DTRACEACT_RAISE (DTRACEACT_PROC_DESTRUCTIVE + 2) 382*0Sstevel@tonic-gate #define DTRACEACT_SYSTEM (DTRACEACT_PROC_DESTRUCTIVE + 3) 383*0Sstevel@tonic-gate #define DTRACEACT_FREOPEN (DTRACEACT_PROC_DESTRUCTIVE + 4) 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate #define DTRACEACT_PROC_CONTROL 0x0300 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate #define DTRACEACT_KERNEL 0x0400 388*0Sstevel@tonic-gate #define DTRACEACT_STACK (DTRACEACT_KERNEL + 1) 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate #define DTRACEACT_KERNEL_DESTRUCTIVE 0x0500 391*0Sstevel@tonic-gate #define DTRACEACT_BREAKPOINT (DTRACEACT_KERNEL_DESTRUCTIVE + 1) 392*0Sstevel@tonic-gate #define DTRACEACT_PANIC (DTRACEACT_KERNEL_DESTRUCTIVE + 2) 393*0Sstevel@tonic-gate #define DTRACEACT_CHILL (DTRACEACT_KERNEL_DESTRUCTIVE + 3) 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate #define DTRACEACT_SPECULATIVE 0x0600 396*0Sstevel@tonic-gate #define DTRACEACT_SPECULATE (DTRACEACT_SPECULATIVE + 1) 397*0Sstevel@tonic-gate #define DTRACEACT_COMMIT (DTRACEACT_SPECULATIVE + 2) 398*0Sstevel@tonic-gate #define DTRACEACT_DISCARD (DTRACEACT_SPECULATIVE + 3) 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate #define DTRACEACT_CLASS(x) ((x) & 0xff00) 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate #define DTRACEACT_ISDESTRUCTIVE(x) \ 403*0Sstevel@tonic-gate (DTRACEACT_CLASS(x) == DTRACEACT_PROC_DESTRUCTIVE || \ 404*0Sstevel@tonic-gate DTRACEACT_CLASS(x) == DTRACEACT_KERNEL_DESTRUCTIVE) 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate #define DTRACEACT_ISSPECULATIVE(x) \ 407*0Sstevel@tonic-gate (DTRACEACT_CLASS(x) == DTRACEACT_SPECULATIVE) 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate #define DTRACEACT_ISPRINTFLIKE(x) \ 410*0Sstevel@tonic-gate ((x) == DTRACEACT_PRINTF || (x) == DTRACEACT_PRINTA || \ 411*0Sstevel@tonic-gate (x) == DTRACEACT_SYSTEM || (x) == DTRACEACT_FREOPEN) 412*0Sstevel@tonic-gate 413*0Sstevel@tonic-gate /* 414*0Sstevel@tonic-gate * DTrace Aggregating Actions 415*0Sstevel@tonic-gate * 416*0Sstevel@tonic-gate * These are functions f(x) for which the following is true: 417*0Sstevel@tonic-gate * 418*0Sstevel@tonic-gate * f(f(x_0) U f(x_1) U ... U f(x_n)) = f(x_0 U x_1 U ... U x_n) 419*0Sstevel@tonic-gate * 420*0Sstevel@tonic-gate * where x_n is a set of arbitrary data. Aggregating actions are in their own 421*0Sstevel@tonic-gate * DTrace action class, DTTRACEACT_AGGREGATION. The macros provided here allow 422*0Sstevel@tonic-gate * for easier processing of the aggregation argument and data payload for a few 423*0Sstevel@tonic-gate * aggregating actions (notably: quantize(), lquantize(), and ustack()). 424*0Sstevel@tonic-gate */ 425*0Sstevel@tonic-gate #define DTRACEACT_AGGREGATION 0x0700 426*0Sstevel@tonic-gate #define DTRACEAGG_COUNT (DTRACEACT_AGGREGATION + 1) 427*0Sstevel@tonic-gate #define DTRACEAGG_MIN (DTRACEACT_AGGREGATION + 2) 428*0Sstevel@tonic-gate #define DTRACEAGG_MAX (DTRACEACT_AGGREGATION + 3) 429*0Sstevel@tonic-gate #define DTRACEAGG_AVG (DTRACEACT_AGGREGATION + 4) 430*0Sstevel@tonic-gate #define DTRACEAGG_SUM (DTRACEACT_AGGREGATION + 5) 431*0Sstevel@tonic-gate #define DTRACEAGG_STDDEV (DTRACEACT_AGGREGATION + 6) 432*0Sstevel@tonic-gate #define DTRACEAGG_QUANTIZE (DTRACEACT_AGGREGATION + 7) 433*0Sstevel@tonic-gate #define DTRACEAGG_LQUANTIZE (DTRACEACT_AGGREGATION + 8) 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate #define DTRACEACT_ISAGG(x) \ 436*0Sstevel@tonic-gate (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION) 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate #define DTRACE_QUANTIZE_NBUCKETS \ 439*0Sstevel@tonic-gate (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate #define DTRACE_QUANTIZE_ZEROBUCKET ((sizeof (uint64_t) * NBBY) - 1) 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate #define DTRACE_QUANTIZE_BUCKETVAL(buck) \ 444*0Sstevel@tonic-gate (int64_t)((buck) < DTRACE_QUANTIZE_ZEROBUCKET ? \ 445*0Sstevel@tonic-gate -(1LL << (DTRACE_QUANTIZE_ZEROBUCKET - 1 - (buck))) : \ 446*0Sstevel@tonic-gate (buck) == DTRACE_QUANTIZE_ZEROBUCKET ? 0 : \ 447*0Sstevel@tonic-gate 1LL << ((buck) - DTRACE_QUANTIZE_ZEROBUCKET - 1)) 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_STEPSHIFT 48 450*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_STEPMASK ((uint64_t)UINT16_MAX << 48) 451*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_LEVELSHIFT 32 452*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_LEVELMASK ((uint64_t)UINT16_MAX << 32) 453*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_BASESHIFT 0 454*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_BASEMASK UINT32_MAX 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_STEP(x) \ 457*0Sstevel@tonic-gate (uint16_t)(((x) & DTRACE_LQUANTIZE_STEPMASK) >> \ 458*0Sstevel@tonic-gate DTRACE_LQUANTIZE_STEPSHIFT) 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_LEVELS(x) \ 461*0Sstevel@tonic-gate (uint16_t)(((x) & DTRACE_LQUANTIZE_LEVELMASK) >> \ 462*0Sstevel@tonic-gate DTRACE_LQUANTIZE_LEVELSHIFT) 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate #define DTRACE_LQUANTIZE_BASE(x) \ 465*0Sstevel@tonic-gate (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \ 466*0Sstevel@tonic-gate DTRACE_LQUANTIZE_BASESHIFT) 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate #define DTRACE_USTACK_NFRAMES(x) (uint32_t)((x) & UINT32_MAX) 469*0Sstevel@tonic-gate #define DTRACE_USTACK_STRSIZE(x) (uint32_t)((x) >> 32) 470*0Sstevel@tonic-gate #define DTRACE_USTACK_ARG(x, y) \ 471*0Sstevel@tonic-gate ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate #ifndef _LP64 474*0Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN 475*0Sstevel@tonic-gate #define DTRACE_PTR(type, name) uint32_t name##pad; type *name 476*0Sstevel@tonic-gate #else 477*0Sstevel@tonic-gate #define DTRACE_PTR(type, name) type *name; uint32_t name##pad 478*0Sstevel@tonic-gate #endif 479*0Sstevel@tonic-gate #else 480*0Sstevel@tonic-gate #define DTRACE_PTR(type, name) type *name 481*0Sstevel@tonic-gate #endif 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate /* 484*0Sstevel@tonic-gate * DTrace Object Format (DOF) 485*0Sstevel@tonic-gate * 486*0Sstevel@tonic-gate * DTrace programs can be persistently encoded in the DOF format so that they 487*0Sstevel@tonic-gate * may be embedded in other programs (for example, in an ELF file) or in the 488*0Sstevel@tonic-gate * dtrace driver configuration file for use in anonymous tracing. The DOF 489*0Sstevel@tonic-gate * format is versioned and extensible so that it can be revised and so that 490*0Sstevel@tonic-gate * internal data structures can be modified or extended compatibly. All DOF 491*0Sstevel@tonic-gate * structures use fixed-size types, so the 32-bit and 64-bit representations 492*0Sstevel@tonic-gate * are identical and consumers can use either data model transparently. 493*0Sstevel@tonic-gate * 494*0Sstevel@tonic-gate * The file layout is structured as follows: 495*0Sstevel@tonic-gate * 496*0Sstevel@tonic-gate * +---------------+-------------------+----- ... ----+---- ... ------+ 497*0Sstevel@tonic-gate * | dof_hdr_t | dof_sec_t[ ... ] | loadable | non-loadable | 498*0Sstevel@tonic-gate * | (file header) | (section headers) | section data | section data | 499*0Sstevel@tonic-gate * +---------------+-------------------+----- ... ----+---- ... ------+ 500*0Sstevel@tonic-gate * |<------------ dof_hdr.dofh_loadsz --------------->| | 501*0Sstevel@tonic-gate * |<------------ dof_hdr.dofh_filesz ------------------------------->| 502*0Sstevel@tonic-gate * 503*0Sstevel@tonic-gate * The file header stores meta-data including a magic number, data model for 504*0Sstevel@tonic-gate * the instrumentation, data encoding, and properties of the DIF code within. 505*0Sstevel@tonic-gate * The header describes its own size and the size of the section headers. By 506*0Sstevel@tonic-gate * convention, an array of section headers follows the file header, and then 507*0Sstevel@tonic-gate * the data for all loadable sections and unloadable sections. This permits 508*0Sstevel@tonic-gate * consumer code to easily download the headers and all loadable data into the 509*0Sstevel@tonic-gate * DTrace driver in one contiguous chunk, omitting other extraneous sections. 510*0Sstevel@tonic-gate * 511*0Sstevel@tonic-gate * The section headers describe the size, offset, alignment, and section type 512*0Sstevel@tonic-gate * for each section. Sections are described using a set of #defines that tell 513*0Sstevel@tonic-gate * the consumer what kind of data is expected. Sections can contain links to 514*0Sstevel@tonic-gate * other sections by storing a dof_secidx_t, an index into the section header 515*0Sstevel@tonic-gate * array, inside of the section data structures. The section header includes 516*0Sstevel@tonic-gate * an entry size so that sections with data arrays can grow their structures. 517*0Sstevel@tonic-gate * 518*0Sstevel@tonic-gate * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which 519*0Sstevel@tonic-gate * are represented themselves as a collection of related DOF sections. This 520*0Sstevel@tonic-gate * permits us to change the set of sections associated with a DIFO over time, 521*0Sstevel@tonic-gate * and also permits us to encode DIFOs that contain different sets of sections. 522*0Sstevel@tonic-gate * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a 523*0Sstevel@tonic-gate * section of type DOF_SECT_DIFOHDR. This section's data is then an array of 524*0Sstevel@tonic-gate * dof_secidx_t's which in turn denote the sections associated with this DIFO. 525*0Sstevel@tonic-gate * 526*0Sstevel@tonic-gate * This loose coupling of the file structure (header and sections) to the 527*0Sstevel@tonic-gate * structure of the DTrace program itself (ECB descriptions, action 528*0Sstevel@tonic-gate * descriptions, and DIFOs) permits activities such as relocation processing 529*0Sstevel@tonic-gate * to occur in a single pass without having to understand D program structure. 530*0Sstevel@tonic-gate * 531*0Sstevel@tonic-gate * Finally, strings are always stored in ELF-style string tables along with a 532*0Sstevel@tonic-gate * string table section index and string table offset. Therefore strings in 533*0Sstevel@tonic-gate * DOF are always arbitrary-length and not bound to the current implementation. 534*0Sstevel@tonic-gate */ 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gate #define DOF_ID_SIZE 16 /* total size of dofh_ident[] in bytes */ 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate typedef struct dof_hdr { 539*0Sstevel@tonic-gate uint8_t dofh_ident[DOF_ID_SIZE]; /* identification bytes (see below) */ 540*0Sstevel@tonic-gate uint32_t dofh_flags; /* file attribute flags (if any) */ 541*0Sstevel@tonic-gate uint32_t dofh_hdrsize; /* size of file header in bytes */ 542*0Sstevel@tonic-gate uint32_t dofh_secsize; /* size of section header in bytes */ 543*0Sstevel@tonic-gate uint32_t dofh_secnum; /* number of section headers */ 544*0Sstevel@tonic-gate uint64_t dofh_secoff; /* file offset of section headers */ 545*0Sstevel@tonic-gate uint64_t dofh_loadsz; /* file size of loadable portion */ 546*0Sstevel@tonic-gate uint64_t dofh_filesz; /* file size of entire DOF file */ 547*0Sstevel@tonic-gate uint64_t dofh_pad; /* reserved for future use */ 548*0Sstevel@tonic-gate } dof_hdr_t; 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate #define DOF_ID_MAG0 0 /* first byte of magic number */ 551*0Sstevel@tonic-gate #define DOF_ID_MAG1 1 /* second byte of magic number */ 552*0Sstevel@tonic-gate #define DOF_ID_MAG2 2 /* third byte of magic number */ 553*0Sstevel@tonic-gate #define DOF_ID_MAG3 3 /* fourth byte of magic number */ 554*0Sstevel@tonic-gate #define DOF_ID_MODEL 4 /* DOF data model (see below) */ 555*0Sstevel@tonic-gate #define DOF_ID_ENCODING 5 /* DOF data encoding (see below) */ 556*0Sstevel@tonic-gate #define DOF_ID_VERSION 6 /* DOF file format major version (see below) */ 557*0Sstevel@tonic-gate #define DOF_ID_DIFVERS 7 /* DIF instruction set version */ 558*0Sstevel@tonic-gate #define DOF_ID_DIFIREG 8 /* DIF integer registers used by compiler */ 559*0Sstevel@tonic-gate #define DOF_ID_DIFTREG 9 /* DIF tuple registers used by compiler */ 560*0Sstevel@tonic-gate #define DOF_ID_PAD 10 /* start of padding bytes (all zeroes) */ 561*0Sstevel@tonic-gate 562*0Sstevel@tonic-gate #define DOF_MAG_MAG0 0x7F /* DOF_ID_MAG[0-3] */ 563*0Sstevel@tonic-gate #define DOF_MAG_MAG1 'D' 564*0Sstevel@tonic-gate #define DOF_MAG_MAG2 'O' 565*0Sstevel@tonic-gate #define DOF_MAG_MAG3 'F' 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate #define DOF_MAG_STRING "\177DOF" 568*0Sstevel@tonic-gate #define DOF_MAG_STRLEN 4 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate #define DOF_MODEL_NONE 0 /* DOF_ID_MODEL */ 571*0Sstevel@tonic-gate #define DOF_MODEL_ILP32 1 572*0Sstevel@tonic-gate #define DOF_MODEL_LP64 2 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate #ifdef _LP64 575*0Sstevel@tonic-gate #define DOF_MODEL_NATIVE DOF_MODEL_LP64 576*0Sstevel@tonic-gate #else 577*0Sstevel@tonic-gate #define DOF_MODEL_NATIVE DOF_MODEL_ILP32 578*0Sstevel@tonic-gate #endif 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate #define DOF_ENCODE_NONE 0 /* DOF_ID_ENCODING */ 581*0Sstevel@tonic-gate #define DOF_ENCODE_LSB 1 582*0Sstevel@tonic-gate #define DOF_ENCODE_MSB 2 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate #ifdef _BIG_ENDIAN 585*0Sstevel@tonic-gate #define DOF_ENCODE_NATIVE DOF_ENCODE_MSB 586*0Sstevel@tonic-gate #else 587*0Sstevel@tonic-gate #define DOF_ENCODE_NATIVE DOF_ENCODE_LSB 588*0Sstevel@tonic-gate #endif 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate #define DOF_VERSION_1 1 /* DOF_ID_VERSION */ 591*0Sstevel@tonic-gate #define DOF_VERSION DOF_VERSION_1 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate #define DOF_FL_VALID 0 /* mask of all valid dofh_flags bits */ 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate typedef uint32_t dof_secidx_t; /* section header table index type */ 596*0Sstevel@tonic-gate typedef uint32_t dof_stridx_t; /* string table index type */ 597*0Sstevel@tonic-gate 598*0Sstevel@tonic-gate #define DOF_SECIDX_NONE (-1U) /* null value for section indices */ 599*0Sstevel@tonic-gate #define DOF_STRIDX_NONE (-1U) /* null value for string indices */ 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate typedef struct dof_sec { 602*0Sstevel@tonic-gate uint32_t dofs_type; /* section type (see below) */ 603*0Sstevel@tonic-gate uint32_t dofs_align; /* section data memory alignment */ 604*0Sstevel@tonic-gate uint32_t dofs_flags; /* section flags (if any) */ 605*0Sstevel@tonic-gate uint32_t dofs_entsize; /* size of section entry (if table) */ 606*0Sstevel@tonic-gate uint64_t dofs_offset; /* offset of section data within file */ 607*0Sstevel@tonic-gate uint64_t dofs_size; /* size of section data in bytes */ 608*0Sstevel@tonic-gate } dof_sec_t; 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate #define DOF_SECT_NONE 0 /* null section */ 611*0Sstevel@tonic-gate #define DOF_SECT_COMMENTS 1 /* compiler comments */ 612*0Sstevel@tonic-gate #define DOF_SECT_SOURCE 2 /* D program source code */ 613*0Sstevel@tonic-gate #define DOF_SECT_ECBDESC 3 /* dof_ecbdesc_t */ 614*0Sstevel@tonic-gate #define DOF_SECT_PROBEDESC 4 /* dof_probedesc_t */ 615*0Sstevel@tonic-gate #define DOF_SECT_ACTDESC 5 /* dof_actdesc_t array */ 616*0Sstevel@tonic-gate #define DOF_SECT_DIFOHDR 6 /* dof_difohdr_t (variable length) */ 617*0Sstevel@tonic-gate #define DOF_SECT_DIF 7 /* uint32_t array of byte code */ 618*0Sstevel@tonic-gate #define DOF_SECT_STRTAB 8 /* string table */ 619*0Sstevel@tonic-gate #define DOF_SECT_VARTAB 9 /* dtrace_difv_t array */ 620*0Sstevel@tonic-gate #define DOF_SECT_RELTAB 10 /* dof_relodesc_t array */ 621*0Sstevel@tonic-gate #define DOF_SECT_TYPTAB 11 /* dtrace_diftype_t array */ 622*0Sstevel@tonic-gate #define DOF_SECT_URELHDR 12 /* dof_relohdr_t (user relocations) */ 623*0Sstevel@tonic-gate #define DOF_SECT_KRELHDR 13 /* dof_relohdr_t (kernel relocations) */ 624*0Sstevel@tonic-gate #define DOF_SECT_OPTDESC 14 /* dof_optdesc_t array */ 625*0Sstevel@tonic-gate #define DOF_SECT_PROVIDER 15 /* dof_provider_t */ 626*0Sstevel@tonic-gate #define DOF_SECT_PROBES 16 /* dof_probe_t array */ 627*0Sstevel@tonic-gate #define DOF_SECT_PRARGS 17 /* uint8_t array (probe arg mappings) */ 628*0Sstevel@tonic-gate #define DOF_SECT_PROFFS 18 /* uint32_t array (probe arg offsets) */ 629*0Sstevel@tonic-gate #define DOF_SECT_INTTAB 19 /* uint64_t array */ 630*0Sstevel@tonic-gate #define DOF_SECT_UTSNAME 20 /* struct utsname */ 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate #define DOF_SECF_LOAD 1 /* section should be loaded */ 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gate typedef struct dof_ecbdesc { 635*0Sstevel@tonic-gate dof_secidx_t dofe_probes; /* link to DOF_SECT_PROBEDESC */ 636*0Sstevel@tonic-gate dof_secidx_t dofe_pred; /* link to DOF_SECT_DIFOHDR */ 637*0Sstevel@tonic-gate dof_secidx_t dofe_actions; /* link to DOF_SECT_ACTDESC */ 638*0Sstevel@tonic-gate uint32_t dofe_pad; /* reserved for future use */ 639*0Sstevel@tonic-gate uint64_t dofe_uarg; /* user-supplied library argument */ 640*0Sstevel@tonic-gate } dof_ecbdesc_t; 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate typedef struct dof_probedesc { 643*0Sstevel@tonic-gate dof_secidx_t dofp_strtab; /* link to DOF_SECT_STRTAB section */ 644*0Sstevel@tonic-gate dof_stridx_t dofp_provider; /* provider string */ 645*0Sstevel@tonic-gate dof_stridx_t dofp_mod; /* module string */ 646*0Sstevel@tonic-gate dof_stridx_t dofp_func; /* function string */ 647*0Sstevel@tonic-gate dof_stridx_t dofp_name; /* name string */ 648*0Sstevel@tonic-gate uint32_t dofp_id; /* probe identifier (or zero) */ 649*0Sstevel@tonic-gate } dof_probedesc_t; 650*0Sstevel@tonic-gate 651*0Sstevel@tonic-gate typedef struct dof_actdesc { 652*0Sstevel@tonic-gate dof_secidx_t dofa_difo; /* link to DOF_SECT_DIFOHDR */ 653*0Sstevel@tonic-gate dof_secidx_t dofa_strtab; /* link to DOF_SECT_STRTAB section */ 654*0Sstevel@tonic-gate uint32_t dofa_kind; /* action kind (DTRACEACT_* constant) */ 655*0Sstevel@tonic-gate uint32_t dofa_ntuple; /* number of subsequent tuple actions */ 656*0Sstevel@tonic-gate uint64_t dofa_arg; /* kind-specific argument */ 657*0Sstevel@tonic-gate uint64_t dofa_uarg; /* user-supplied argument */ 658*0Sstevel@tonic-gate } dof_actdesc_t; 659*0Sstevel@tonic-gate 660*0Sstevel@tonic-gate typedef struct dof_difohdr { 661*0Sstevel@tonic-gate dtrace_diftype_t dofd_rtype; /* return type for this fragment */ 662*0Sstevel@tonic-gate dof_secidx_t dofd_links[1]; /* variable length array of indices */ 663*0Sstevel@tonic-gate } dof_difohdr_t; 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate typedef struct dof_relohdr { 666*0Sstevel@tonic-gate dof_secidx_t dofr_strtab; /* link to DOF_SECT_STRTAB for names */ 667*0Sstevel@tonic-gate dof_secidx_t dofr_relsec; /* link to DOF_SECT_RELTAB for relos */ 668*0Sstevel@tonic-gate dof_secidx_t dofr_tgtsec; /* link to section we are relocating */ 669*0Sstevel@tonic-gate } dof_relohdr_t; 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate typedef struct dof_relodesc { 672*0Sstevel@tonic-gate dof_stridx_t dofr_name; /* string name of relocation symbol */ 673*0Sstevel@tonic-gate uint32_t dofr_type; /* relo type (DOF_RELO_* constant) */ 674*0Sstevel@tonic-gate uint64_t dofr_offset; /* byte offset for relocation */ 675*0Sstevel@tonic-gate uint64_t dofr_data; /* additional type-specific data */ 676*0Sstevel@tonic-gate } dof_relodesc_t; 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gate #define DOF_RELO_NONE 0 /* empty relocation entry */ 679*0Sstevel@tonic-gate #define DOF_RELO_SETX 1 /* relocate setx value */ 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate typedef struct dof_optdesc { 682*0Sstevel@tonic-gate uint32_t dofo_option; /* option identifier */ 683*0Sstevel@tonic-gate dof_secidx_t dofo_strtab; /* string table, if string option */ 684*0Sstevel@tonic-gate uint64_t dofo_value; /* option value or string index */ 685*0Sstevel@tonic-gate } dof_optdesc_t; 686*0Sstevel@tonic-gate 687*0Sstevel@tonic-gate typedef uint32_t dof_attr_t; /* encoded stability attributes */ 688*0Sstevel@tonic-gate 689*0Sstevel@tonic-gate #define DOF_ATTR(n, d, c) (((n) << 24) | ((d) << 16) | ((c) << 8)) 690*0Sstevel@tonic-gate #define DOF_ATTR_NAME(a) (((a) >> 24) & 0xff) 691*0Sstevel@tonic-gate #define DOF_ATTR_DATA(a) (((a) >> 16) & 0xff) 692*0Sstevel@tonic-gate #define DOF_ATTR_CLASS(a) (((a) >> 8) & 0xff) 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate typedef struct dof_provider { 695*0Sstevel@tonic-gate dof_secidx_t dofpv_strtab; /* link to DOF_SECT_STRTAB section */ 696*0Sstevel@tonic-gate dof_secidx_t dofpv_probes; /* link to DOF_SECT_PROBES section */ 697*0Sstevel@tonic-gate dof_secidx_t dofpv_prargs; /* link to DOF_SECT_PRARGS section */ 698*0Sstevel@tonic-gate dof_secidx_t dofpv_proffs; /* link to DOF_SECT_PROFFS section */ 699*0Sstevel@tonic-gate dof_stridx_t dofpv_name; /* provider name string */ 700*0Sstevel@tonic-gate dof_attr_t dofpv_provattr; /* provider attributes */ 701*0Sstevel@tonic-gate dof_attr_t dofpv_modattr; /* module attributes */ 702*0Sstevel@tonic-gate dof_attr_t dofpv_funcattr; /* function attributes */ 703*0Sstevel@tonic-gate dof_attr_t dofpv_nameattr; /* name attributes */ 704*0Sstevel@tonic-gate dof_attr_t dofpv_argsattr; /* args attributes */ 705*0Sstevel@tonic-gate } dof_provider_t; 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate typedef struct dof_probe { 708*0Sstevel@tonic-gate uint64_t dofpr_addr; /* probe base address or offset */ 709*0Sstevel@tonic-gate dof_stridx_t dofpr_func; /* probe function string */ 710*0Sstevel@tonic-gate dof_stridx_t dofpr_name; /* probe name string */ 711*0Sstevel@tonic-gate dof_stridx_t dofpr_nargv; /* native argument type strings */ 712*0Sstevel@tonic-gate dof_stridx_t dofpr_xargv; /* translated argument type strings */ 713*0Sstevel@tonic-gate uint32_t dofpr_argidx; /* index of first argument mapping */ 714*0Sstevel@tonic-gate uint32_t dofpr_offidx; /* index of first offset entry */ 715*0Sstevel@tonic-gate uint8_t dofpr_nargc; /* native argument count */ 716*0Sstevel@tonic-gate uint8_t dofpr_xargc; /* translated argument count */ 717*0Sstevel@tonic-gate uint16_t dofpr_noffs; /* number of offset entries for probe */ 718*0Sstevel@tonic-gate uint32_t dofpr_pad; /* reserved for future use */ 719*0Sstevel@tonic-gate } dof_probe_t; 720*0Sstevel@tonic-gate 721*0Sstevel@tonic-gate /* 722*0Sstevel@tonic-gate * DTrace Intermediate Format Object (DIFO) 723*0Sstevel@tonic-gate * 724*0Sstevel@tonic-gate * A DIFO is used to store the compiled DIF for a D expression, its return 725*0Sstevel@tonic-gate * type, and its string and variable tables. The string table is a single 726*0Sstevel@tonic-gate * buffer of character data into which sets instructions and variable 727*0Sstevel@tonic-gate * references can reference strings using a byte offset. The variable table 728*0Sstevel@tonic-gate * is an array of dtrace_difv_t structures that describe the name and type of 729*0Sstevel@tonic-gate * each variable and the id used in the DIF code. This structure is described 730*0Sstevel@tonic-gate * above in the DIF section of this header file. The DIFO is used at both 731*0Sstevel@tonic-gate * user-level (in the library) and in the kernel, but the structure is never 732*0Sstevel@tonic-gate * passed between the two: the DOF structures form the only interface. As a 733*0Sstevel@tonic-gate * result, the definition can change depending on the presence of _KERNEL. 734*0Sstevel@tonic-gate */ 735*0Sstevel@tonic-gate typedef struct dtrace_difo { 736*0Sstevel@tonic-gate dif_instr_t *dtdo_buf; /* instruction buffer */ 737*0Sstevel@tonic-gate uint64_t *dtdo_inttab; /* integer table (optional) */ 738*0Sstevel@tonic-gate char *dtdo_strtab; /* string table (optional) */ 739*0Sstevel@tonic-gate dtrace_difv_t *dtdo_vartab; /* variable table (optional) */ 740*0Sstevel@tonic-gate uint_t dtdo_len; /* length of instruction buffer */ 741*0Sstevel@tonic-gate uint_t dtdo_intlen; /* length of integer table */ 742*0Sstevel@tonic-gate uint_t dtdo_strlen; /* length of string table */ 743*0Sstevel@tonic-gate uint_t dtdo_varlen; /* length of variable table */ 744*0Sstevel@tonic-gate dtrace_diftype_t dtdo_rtype; /* return type */ 745*0Sstevel@tonic-gate uint_t dtdo_refcnt; /* owner reference count */ 746*0Sstevel@tonic-gate uint_t dtdo_destructive; /* invokes destructive subroutines */ 747*0Sstevel@tonic-gate #ifndef _KERNEL 748*0Sstevel@tonic-gate dof_relodesc_t *dtdo_kreltab; /* kernel relocations */ 749*0Sstevel@tonic-gate dof_relodesc_t *dtdo_ureltab; /* user relocations */ 750*0Sstevel@tonic-gate uint32_t dtdo_krelen; /* length of krelo table */ 751*0Sstevel@tonic-gate uint32_t dtdo_urelen; /* length of urelo table */ 752*0Sstevel@tonic-gate #endif 753*0Sstevel@tonic-gate } dtrace_difo_t; 754*0Sstevel@tonic-gate 755*0Sstevel@tonic-gate /* 756*0Sstevel@tonic-gate * DTrace Enabling Description Structures 757*0Sstevel@tonic-gate * 758*0Sstevel@tonic-gate * When DTrace is tracking the description of a DTrace enabling entity (probe, 759*0Sstevel@tonic-gate * predicate, action, ECB, record, etc.), it does so in a description 760*0Sstevel@tonic-gate * structure. These structures all end in "desc", and are used at both 761*0Sstevel@tonic-gate * user-level and in the kernel -- but (with the exception of 762*0Sstevel@tonic-gate * dtrace_probedesc_t) they are never passed between them. Typically, 763*0Sstevel@tonic-gate * user-level will use the description structures when assembling an enabling. 764*0Sstevel@tonic-gate * It will then distill those description structures into a DOF object (see 765*0Sstevel@tonic-gate * above), and send it into the kernel. The kernel will again use the 766*0Sstevel@tonic-gate * description structures to create a description of the enabling as it reads 767*0Sstevel@tonic-gate * the DOF. When the description is complete, the enabling will be actually 768*0Sstevel@tonic-gate * created -- turning it into the structures that represent the enabling 769*0Sstevel@tonic-gate * instead of merely describing it. Not surprisingly, the description 770*0Sstevel@tonic-gate * structures bear a strong resemblance to the DOF structures that act as their 771*0Sstevel@tonic-gate * conduit. 772*0Sstevel@tonic-gate */ 773*0Sstevel@tonic-gate struct dtrace_predicate; 774*0Sstevel@tonic-gate 775*0Sstevel@tonic-gate typedef struct dtrace_probedesc { 776*0Sstevel@tonic-gate dtrace_id_t dtpd_id; /* probe identifier */ 777*0Sstevel@tonic-gate char dtpd_provider[DTRACE_PROVNAMELEN]; /* probe provider name */ 778*0Sstevel@tonic-gate char dtpd_mod[DTRACE_MODNAMELEN]; /* probe module name */ 779*0Sstevel@tonic-gate char dtpd_func[DTRACE_FUNCNAMELEN]; /* probe function name */ 780*0Sstevel@tonic-gate char dtpd_name[DTRACE_NAMELEN]; /* probe name */ 781*0Sstevel@tonic-gate } dtrace_probedesc_t; 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate typedef struct dtrace_repldesc { 784*0Sstevel@tonic-gate dtrace_probedesc_t dtrpd_match; /* probe descr. to match */ 785*0Sstevel@tonic-gate dtrace_probedesc_t dtrpd_create; /* probe descr. to create */ 786*0Sstevel@tonic-gate } dtrace_repldesc_t; 787*0Sstevel@tonic-gate 788*0Sstevel@tonic-gate typedef struct dtrace_preddesc { 789*0Sstevel@tonic-gate dtrace_difo_t *dtpdd_difo; /* pointer to DIF object */ 790*0Sstevel@tonic-gate struct dtrace_predicate *dtpdd_predicate; /* pointer to predicate */ 791*0Sstevel@tonic-gate } dtrace_preddesc_t; 792*0Sstevel@tonic-gate 793*0Sstevel@tonic-gate typedef struct dtrace_actdesc { 794*0Sstevel@tonic-gate dtrace_difo_t *dtad_difo; /* pointer to DIF object */ 795*0Sstevel@tonic-gate struct dtrace_actdesc *dtad_next; /* next action */ 796*0Sstevel@tonic-gate dtrace_actkind_t dtad_kind; /* kind of action */ 797*0Sstevel@tonic-gate uint32_t dtad_ntuple; /* number in tuple */ 798*0Sstevel@tonic-gate uint64_t dtad_arg; /* action argument */ 799*0Sstevel@tonic-gate uint64_t dtad_uarg; /* user argument */ 800*0Sstevel@tonic-gate int dtad_refcnt; /* reference count */ 801*0Sstevel@tonic-gate } dtrace_actdesc_t; 802*0Sstevel@tonic-gate 803*0Sstevel@tonic-gate typedef struct dtrace_ecbdesc { 804*0Sstevel@tonic-gate dtrace_actdesc_t *dted_action; /* action description(s) */ 805*0Sstevel@tonic-gate dtrace_preddesc_t dted_pred; /* predicate description */ 806*0Sstevel@tonic-gate dtrace_probedesc_t dted_probe; /* probe description */ 807*0Sstevel@tonic-gate uint64_t dted_uarg; /* library argument */ 808*0Sstevel@tonic-gate int dted_refcnt; /* reference count */ 809*0Sstevel@tonic-gate } dtrace_ecbdesc_t; 810*0Sstevel@tonic-gate 811*0Sstevel@tonic-gate /* 812*0Sstevel@tonic-gate * DTrace Metadata Description Structures 813*0Sstevel@tonic-gate * 814*0Sstevel@tonic-gate * DTrace separates the trace data stream from the metadata stream. The only 815*0Sstevel@tonic-gate * metadata tokens placed in the data stream are enabled probe identifiers 816*0Sstevel@tonic-gate * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order 817*0Sstevel@tonic-gate * to determine the structure of the data, DTrace consumers pass the token to 818*0Sstevel@tonic-gate * the kernel, and receive in return a corresponding description of the enabled 819*0Sstevel@tonic-gate * probe (via the dtrace_eprobedesc structure) or the aggregation (via the 820*0Sstevel@tonic-gate * dtrace_aggdesc structure). Both of these structures are expressed in terms 821*0Sstevel@tonic-gate * of record descriptions (via the dtrace_recdesc structure) that describe the 822*0Sstevel@tonic-gate * exact structure of the data. Some record descriptions may also contain a 823*0Sstevel@tonic-gate * format identifier; this additional bit of metadata can be retrieved from the 824*0Sstevel@tonic-gate * kernel, for which a format description is returned via the dtrace_fmtdesc 825*0Sstevel@tonic-gate * structure. Note that all four of these structures must be bitness-neutral 826*0Sstevel@tonic-gate * to allow for a 32-bit DTrace consumer on a 64-bit kernel. 827*0Sstevel@tonic-gate */ 828*0Sstevel@tonic-gate typedef struct dtrace_recdesc { 829*0Sstevel@tonic-gate dtrace_actkind_t dtrd_action; /* kind of action */ 830*0Sstevel@tonic-gate uint32_t dtrd_size; /* size of record */ 831*0Sstevel@tonic-gate uint32_t dtrd_offset; /* offset in ECB's data */ 832*0Sstevel@tonic-gate uint16_t dtrd_alignment; /* required alignment */ 833*0Sstevel@tonic-gate uint16_t dtrd_format; /* format, if any */ 834*0Sstevel@tonic-gate uint64_t dtrd_arg; /* action argument */ 835*0Sstevel@tonic-gate uint64_t dtrd_uarg; /* user argument */ 836*0Sstevel@tonic-gate } dtrace_recdesc_t; 837*0Sstevel@tonic-gate 838*0Sstevel@tonic-gate typedef struct dtrace_eprobedesc { 839*0Sstevel@tonic-gate dtrace_epid_t dtepd_epid; /* enabled probe ID */ 840*0Sstevel@tonic-gate dtrace_id_t dtepd_probeid; /* probe ID */ 841*0Sstevel@tonic-gate uint64_t dtepd_uarg; /* library argument */ 842*0Sstevel@tonic-gate uint32_t dtepd_size; /* total size */ 843*0Sstevel@tonic-gate int dtepd_nrecs; /* number of records */ 844*0Sstevel@tonic-gate dtrace_recdesc_t dtepd_rec[1]; /* records themselves */ 845*0Sstevel@tonic-gate } dtrace_eprobedesc_t; 846*0Sstevel@tonic-gate 847*0Sstevel@tonic-gate typedef struct dtrace_aggdesc { 848*0Sstevel@tonic-gate DTRACE_PTR(char, dtagd_name); /* not filled in by kernel */ 849*0Sstevel@tonic-gate int dtagd_flags; /* not filled in by kernel */ 850*0Sstevel@tonic-gate dtrace_aggid_t dtagd_id; /* aggregation ID */ 851*0Sstevel@tonic-gate dtrace_epid_t dtagd_epid; /* enabled probe ID */ 852*0Sstevel@tonic-gate uint32_t dtagd_size; /* size in bytes */ 853*0Sstevel@tonic-gate int dtagd_nrecs; /* number of records */ 854*0Sstevel@tonic-gate uint32_t dtagd_pad; /* explicit padding */ 855*0Sstevel@tonic-gate dtrace_recdesc_t dtagd_rec[1]; /* record descriptions */ 856*0Sstevel@tonic-gate } dtrace_aggdesc_t; 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate typedef struct dtrace_fmtdesc { 859*0Sstevel@tonic-gate DTRACE_PTR(char, dtfd_string); /* format string */ 860*0Sstevel@tonic-gate int dtfd_length; /* length of format string */ 861*0Sstevel@tonic-gate uint16_t dtfd_format; /* format identifier */ 862*0Sstevel@tonic-gate } dtrace_fmtdesc_t; 863*0Sstevel@tonic-gate 864*0Sstevel@tonic-gate #define DTRACE_SIZEOF_EPROBEDESC(desc) \ 865*0Sstevel@tonic-gate (sizeof (dtrace_eprobedesc_t) + ((desc)->dtepd_nrecs ? \ 866*0Sstevel@tonic-gate (((desc)->dtepd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 867*0Sstevel@tonic-gate 868*0Sstevel@tonic-gate #define DTRACE_SIZEOF_AGGDESC(desc) \ 869*0Sstevel@tonic-gate (sizeof (dtrace_aggdesc_t) + ((desc)->dtagd_nrecs ? \ 870*0Sstevel@tonic-gate (((desc)->dtagd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 871*0Sstevel@tonic-gate 872*0Sstevel@tonic-gate /* 873*0Sstevel@tonic-gate * DTrace Option Interface 874*0Sstevel@tonic-gate * 875*0Sstevel@tonic-gate * Run-time DTrace options are set and retrieved via DOF_SECT_OPTDESC sections 876*0Sstevel@tonic-gate * in a DOF image. The dof_optdesc structure contains an option identifier and 877*0Sstevel@tonic-gate * an option value. The valid option identifiers are found below; the mapping 878*0Sstevel@tonic-gate * between option identifiers and option identifying strings is maintained at 879*0Sstevel@tonic-gate * user-level. Note that the value of DTRACEOPT_UNSET is such that all of the 880*0Sstevel@tonic-gate * following are potentially valid option values: all positive integers, zero 881*0Sstevel@tonic-gate * and negative one. Some options (notably "bufpolicy" and "bufresize") take 882*0Sstevel@tonic-gate * predefined tokens as their values; these are defined with 883*0Sstevel@tonic-gate * DTRACEOPT_{option}_{token}. 884*0Sstevel@tonic-gate */ 885*0Sstevel@tonic-gate #define DTRACEOPT_BUFSIZE 0 /* buffer size */ 886*0Sstevel@tonic-gate #define DTRACEOPT_BUFPOLICY 1 /* buffer policy */ 887*0Sstevel@tonic-gate #define DTRACEOPT_DYNVARSIZE 2 /* dynamic variable size */ 888*0Sstevel@tonic-gate #define DTRACEOPT_AGGSIZE 3 /* aggregation size */ 889*0Sstevel@tonic-gate #define DTRACEOPT_SPECSIZE 4 /* speculation size */ 890*0Sstevel@tonic-gate #define DTRACEOPT_NSPEC 5 /* number of speculations */ 891*0Sstevel@tonic-gate #define DTRACEOPT_STRSIZE 6 /* string size */ 892*0Sstevel@tonic-gate #define DTRACEOPT_CLEANRATE 7 /* dynvar cleaning rate */ 893*0Sstevel@tonic-gate #define DTRACEOPT_CPU 8 /* CPU to trace */ 894*0Sstevel@tonic-gate #define DTRACEOPT_BUFRESIZE 9 /* buffer resizing policy */ 895*0Sstevel@tonic-gate #define DTRACEOPT_GRABANON 10 /* grab anonymous state, if any */ 896*0Sstevel@tonic-gate #define DTRACEOPT_FLOWINDENT 11 /* indent function entry/return */ 897*0Sstevel@tonic-gate #define DTRACEOPT_QUIET 12 /* only output explicitly traced data */ 898*0Sstevel@tonic-gate #define DTRACEOPT_STACKFRAMES 13 /* number of stack frames */ 899*0Sstevel@tonic-gate #define DTRACEOPT_USTACKFRAMES 14 /* number of user stack frames */ 900*0Sstevel@tonic-gate #define DTRACEOPT_AGGRATE 15 /* aggregation snapshot rate */ 901*0Sstevel@tonic-gate #define DTRACEOPT_SWITCHRATE 16 /* buffer switching rate */ 902*0Sstevel@tonic-gate #define DTRACEOPT_STATUSRATE 17 /* status rate */ 903*0Sstevel@tonic-gate #define DTRACEOPT_DESTRUCTIVE 18 /* destructive actions allowed */ 904*0Sstevel@tonic-gate #define DTRACEOPT_STACKINDENT 19 /* output indent for stack traces */ 905*0Sstevel@tonic-gate #define DTRACEOPT_RAWBYTES 20 /* always print bytes in raw form */ 906*0Sstevel@tonic-gate #define DTRACEOPT_JSTACKFRAMES 21 /* number of jstack() frames */ 907*0Sstevel@tonic-gate #define DTRACEOPT_JSTACKSTRSIZE 22 /* size of jstack() string table */ 908*0Sstevel@tonic-gate #define DTRACEOPT_MAX 23 /* number of options */ 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate #define DTRACEOPT_UNSET (dtrace_optval_t)-2 /* unset option */ 911*0Sstevel@tonic-gate 912*0Sstevel@tonic-gate #define DTRACEOPT_BUFPOLICY_RING 0 /* ring buffer */ 913*0Sstevel@tonic-gate #define DTRACEOPT_BUFPOLICY_FILL 1 /* fill buffer, then stop */ 914*0Sstevel@tonic-gate #define DTRACEOPT_BUFPOLICY_SWITCH 2 /* switch buffers */ 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate #define DTRACEOPT_BUFRESIZE_AUTO 0 /* automatic resizing */ 917*0Sstevel@tonic-gate #define DTRACEOPT_BUFRESIZE_MANUAL 1 /* manual resizing */ 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate /* 920*0Sstevel@tonic-gate * DTrace Buffer Interface 921*0Sstevel@tonic-gate * 922*0Sstevel@tonic-gate * In order to get a snapshot of the principal or aggregation buffer, 923*0Sstevel@tonic-gate * user-level passes a buffer description to the kernel with the dtrace_bufdesc 924*0Sstevel@tonic-gate * structure. This describes which CPU user-level is interested in, and 925*0Sstevel@tonic-gate * where user-level wishes the kernel to snapshot the buffer to (the 926*0Sstevel@tonic-gate * dtbd_data field). The kernel uses the same structure to pass back some 927*0Sstevel@tonic-gate * information regarding the buffer: the size of data actually copied out, the 928*0Sstevel@tonic-gate * number of drops, the number of errors, and the offset of the oldest record. 929*0Sstevel@tonic-gate * If the buffer policy is a "switch" policy, taking a snapshot of the 930*0Sstevel@tonic-gate * principal buffer has the additional effect of switching the active and 931*0Sstevel@tonic-gate * inactive buffers. Taking a snapshot of the aggregation buffer _always_ has 932*0Sstevel@tonic-gate * the additional effect of switching the active and inactive buffers. 933*0Sstevel@tonic-gate */ 934*0Sstevel@tonic-gate typedef struct dtrace_bufdesc { 935*0Sstevel@tonic-gate uint64_t dtbd_size; /* size of buffer */ 936*0Sstevel@tonic-gate uint32_t dtbd_cpu; /* CPU or DTRACE_CPUALL */ 937*0Sstevel@tonic-gate uint32_t dtbd_errors; /* number of errors */ 938*0Sstevel@tonic-gate uint64_t dtbd_drops; /* number of drops */ 939*0Sstevel@tonic-gate DTRACE_PTR(char, dtbd_data); /* data */ 940*0Sstevel@tonic-gate uint64_t dtbd_oldest; /* offset of oldest record */ 941*0Sstevel@tonic-gate } dtrace_bufdesc_t; 942*0Sstevel@tonic-gate 943*0Sstevel@tonic-gate /* 944*0Sstevel@tonic-gate * DTrace Status 945*0Sstevel@tonic-gate * 946*0Sstevel@tonic-gate * The status of DTrace is relayed via the dtrace_status structure. This 947*0Sstevel@tonic-gate * structure contains members to count drops other than the capacity drops 948*0Sstevel@tonic-gate * available via the buffer interface (see above). This consists of dynamic 949*0Sstevel@tonic-gate * drops (including capacity dynamic drops, rinsing drops and dirty drops), and 950*0Sstevel@tonic-gate * speculative drops (including capacity speculative drops, drops due to busy 951*0Sstevel@tonic-gate * speculative buffers and drops due to unavailable speculative buffers). 952*0Sstevel@tonic-gate * Additionally, the status structure contains a field to indicate the number 953*0Sstevel@tonic-gate * of "fill"-policy buffers have been filled and a boolean field to indicate 954*0Sstevel@tonic-gate * that exit() has been called. If the dtst_exiting field is non-zero, no 955*0Sstevel@tonic-gate * further data will be generated until tracing is stopped (at which time any 956*0Sstevel@tonic-gate * enablings of the END action will be processed); if user-level sees that 957*0Sstevel@tonic-gate * this field is non-zero, tracing should be stopped as soon as possible. 958*0Sstevel@tonic-gate */ 959*0Sstevel@tonic-gate typedef struct dtrace_status { 960*0Sstevel@tonic-gate uint64_t dtst_dyndrops; /* dynamic drops */ 961*0Sstevel@tonic-gate uint64_t dtst_dyndrops_rinsing; /* dyn drops due to rinsing */ 962*0Sstevel@tonic-gate uint64_t dtst_dyndrops_dirty; /* dyn drops due to dirty */ 963*0Sstevel@tonic-gate uint64_t dtst_specdrops; /* speculative drops */ 964*0Sstevel@tonic-gate uint64_t dtst_specdrops_busy; /* spec drops due to busy */ 965*0Sstevel@tonic-gate uint64_t dtst_specdrops_unavail; /* spec drops due to unavail */ 966*0Sstevel@tonic-gate uint64_t dtst_errors; /* total errors */ 967*0Sstevel@tonic-gate uint64_t dtst_filled; /* number of filled bufs */ 968*0Sstevel@tonic-gate char dtst_killed; /* non-zero if killed */ 969*0Sstevel@tonic-gate char dtst_exiting; /* non-zero if exit() called */ 970*0Sstevel@tonic-gate char dtst_pad[6]; /* pad out to 64-bit align */ 971*0Sstevel@tonic-gate } dtrace_status_t; 972*0Sstevel@tonic-gate 973*0Sstevel@tonic-gate /* 974*0Sstevel@tonic-gate * DTrace Configuration 975*0Sstevel@tonic-gate * 976*0Sstevel@tonic-gate * User-level may need to understand some elements of the kernel DTrace 977*0Sstevel@tonic-gate * configuration in order to generate correct DIF. This information is 978*0Sstevel@tonic-gate * conveyed via the dtrace_conf structure. 979*0Sstevel@tonic-gate */ 980*0Sstevel@tonic-gate typedef struct dtrace_conf { 981*0Sstevel@tonic-gate uint_t dtc_difversion; /* supported DIF version */ 982*0Sstevel@tonic-gate uint_t dtc_difintregs; /* # of DIF integer registers */ 983*0Sstevel@tonic-gate uint_t dtc_diftupregs; /* # of DIF tuple registers */ 984*0Sstevel@tonic-gate uint_t dtc_ctfmodel; /* CTF data model */ 985*0Sstevel@tonic-gate uint_t dtc_pad[8]; /* reserved for future use */ 986*0Sstevel@tonic-gate } dtrace_conf_t; 987*0Sstevel@tonic-gate 988*0Sstevel@tonic-gate /* 989*0Sstevel@tonic-gate * DTrace Faults 990*0Sstevel@tonic-gate * 991*0Sstevel@tonic-gate * The constants below DTRACEFLT_LIBRARY indicate probe processing faults; 992*0Sstevel@tonic-gate * constants at or above DTRACEFLT_LIBRARY indicate faults in probe 993*0Sstevel@tonic-gate * postprocessing at user-level. Probe processing faults induce an ERROR 994*0Sstevel@tonic-gate * probe and are replicated in unistd.d to allow users' ERROR probes to decode 995*0Sstevel@tonic-gate * the error condition using thse symbolic labels. 996*0Sstevel@tonic-gate */ 997*0Sstevel@tonic-gate #define DTRACEFLT_UNKNOWN 0 /* Unknown fault */ 998*0Sstevel@tonic-gate #define DTRACEFLT_BADADDR 1 /* Bad address */ 999*0Sstevel@tonic-gate #define DTRACEFLT_BADALIGN 2 /* Bad alignment */ 1000*0Sstevel@tonic-gate #define DTRACEFLT_ILLOP 3 /* Illegal operation */ 1001*0Sstevel@tonic-gate #define DTRACEFLT_DIVZERO 4 /* Divide-by-zero */ 1002*0Sstevel@tonic-gate #define DTRACEFLT_NOSCRATCH 5 /* Out of scratch space */ 1003*0Sstevel@tonic-gate #define DTRACEFLT_KPRIV 6 /* Illegal kernel access */ 1004*0Sstevel@tonic-gate #define DTRACEFLT_UPRIV 7 /* Illegal user access */ 1005*0Sstevel@tonic-gate #define DTRACEFLT_TUPOFLOW 8 /* Tuple stack overflow */ 1006*0Sstevel@tonic-gate 1007*0Sstevel@tonic-gate #define DTRACEFLT_LIBRARY 1000 /* Library-level fault */ 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate /* 1010*0Sstevel@tonic-gate * DTrace Argument Types 1011*0Sstevel@tonic-gate * 1012*0Sstevel@tonic-gate * Because it would waste both space and time, argument types do not reside 1013*0Sstevel@tonic-gate * with the probe. In order to determine argument types for args[X] 1014*0Sstevel@tonic-gate * variables, the D compiler queries for argument types on a probe-by-probe 1015*0Sstevel@tonic-gate * basis. (This optimizes for the common case that arguments are either not 1016*0Sstevel@tonic-gate * used or used in an untyped fashion.) Typed arguments are specified with a 1017*0Sstevel@tonic-gate * string of the type name in the dtragd_native member of the argument 1018*0Sstevel@tonic-gate * description structure. Typed arguments may be further translated to types 1019*0Sstevel@tonic-gate * of greater stability; the provider indicates such a translated argument by 1020*0Sstevel@tonic-gate * filling in the dtargd_xlate member with the string of the translated type. 1021*0Sstevel@tonic-gate * Finally, the provider may indicate which argument value a given argument 1022*0Sstevel@tonic-gate * maps to by setting the dtargd_mapping member -- allowing a single argument 1023*0Sstevel@tonic-gate * to map to multiple args[X] variables. 1024*0Sstevel@tonic-gate */ 1025*0Sstevel@tonic-gate typedef struct dtrace_argdesc { 1026*0Sstevel@tonic-gate dtrace_id_t dtargd_id; /* probe identifier */ 1027*0Sstevel@tonic-gate int dtargd_ndx; /* arg number (-1 iff none) */ 1028*0Sstevel@tonic-gate int dtargd_mapping; /* value mapping */ 1029*0Sstevel@tonic-gate char dtargd_native[DTRACE_ARGTYPELEN]; /* native type name */ 1030*0Sstevel@tonic-gate char dtargd_xlate[DTRACE_ARGTYPELEN]; /* translated type name */ 1031*0Sstevel@tonic-gate } dtrace_argdesc_t; 1032*0Sstevel@tonic-gate 1033*0Sstevel@tonic-gate /* 1034*0Sstevel@tonic-gate * DTrace Stability Attributes 1035*0Sstevel@tonic-gate * 1036*0Sstevel@tonic-gate * Each DTrace provider advertises the name and data stability of each of its 1037*0Sstevel@tonic-gate * probe description components, as well as its architectural dependencies. 1038*0Sstevel@tonic-gate * The D compiler can query the provider attributes (dtrace_pattr_t below) in 1039*0Sstevel@tonic-gate * order to compute the properties of an input program and report them. 1040*0Sstevel@tonic-gate */ 1041*0Sstevel@tonic-gate typedef uint8_t dtrace_stability_t; /* stability code (see attributes(5)) */ 1042*0Sstevel@tonic-gate typedef uint8_t dtrace_class_t; /* architectural dependency class */ 1043*0Sstevel@tonic-gate 1044*0Sstevel@tonic-gate #define DTRACE_STABILITY_INTERNAL 0 /* private to DTrace itself */ 1045*0Sstevel@tonic-gate #define DTRACE_STABILITY_PRIVATE 1 /* private to Sun (see docs) */ 1046*0Sstevel@tonic-gate #define DTRACE_STABILITY_OBSOLETE 2 /* scheduled for removal */ 1047*0Sstevel@tonic-gate #define DTRACE_STABILITY_EXTERNAL 3 /* not controlled by Sun */ 1048*0Sstevel@tonic-gate #define DTRACE_STABILITY_UNSTABLE 4 /* new or rapidly changing */ 1049*0Sstevel@tonic-gate #define DTRACE_STABILITY_EVOLVING 5 /* less rapidly changing */ 1050*0Sstevel@tonic-gate #define DTRACE_STABILITY_STABLE 6 /* mature interface from Sun */ 1051*0Sstevel@tonic-gate #define DTRACE_STABILITY_STANDARD 7 /* industry standard */ 1052*0Sstevel@tonic-gate #define DTRACE_STABILITY_MAX 7 /* maximum valid stability */ 1053*0Sstevel@tonic-gate 1054*0Sstevel@tonic-gate #define DTRACE_CLASS_UNKNOWN 0 /* unknown architectural dependency */ 1055*0Sstevel@tonic-gate #define DTRACE_CLASS_CPU 1 /* CPU-module-specific */ 1056*0Sstevel@tonic-gate #define DTRACE_CLASS_PLATFORM 2 /* platform-specific (uname -i) */ 1057*0Sstevel@tonic-gate #define DTRACE_CLASS_GROUP 3 /* hardware-group-specific (uname -m) */ 1058*0Sstevel@tonic-gate #define DTRACE_CLASS_ISA 4 /* ISA-specific (uname -p) */ 1059*0Sstevel@tonic-gate #define DTRACE_CLASS_COMMON 5 /* common to all systems */ 1060*0Sstevel@tonic-gate #define DTRACE_CLASS_MAX 5 /* maximum valid class */ 1061*0Sstevel@tonic-gate 1062*0Sstevel@tonic-gate #define DTRACE_PRIV_NONE 0x0000 1063*0Sstevel@tonic-gate #define DTRACE_PRIV_KERNEL 0x0001 1064*0Sstevel@tonic-gate #define DTRACE_PRIV_USER 0x0002 1065*0Sstevel@tonic-gate #define DTRACE_PRIV_PROC 0x0004 1066*0Sstevel@tonic-gate #define DTRACE_PRIV_OWNER 0x0008 1067*0Sstevel@tonic-gate 1068*0Sstevel@tonic-gate #define DTRACE_PRIV_ALL \ 1069*0Sstevel@tonic-gate (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ 1070*0Sstevel@tonic-gate DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER) 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate typedef struct dtrace_ppriv { 1073*0Sstevel@tonic-gate uint32_t dtpp_flags; /* privilege flags */ 1074*0Sstevel@tonic-gate uid_t dtpp_uid; /* user ID */ 1075*0Sstevel@tonic-gate } dtrace_ppriv_t; 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate typedef struct dtrace_attribute { 1078*0Sstevel@tonic-gate dtrace_stability_t dtat_name; /* entity name stability */ 1079*0Sstevel@tonic-gate dtrace_stability_t dtat_data; /* entity data stability */ 1080*0Sstevel@tonic-gate dtrace_class_t dtat_class; /* entity data dependency */ 1081*0Sstevel@tonic-gate } dtrace_attribute_t; 1082*0Sstevel@tonic-gate 1083*0Sstevel@tonic-gate typedef struct dtrace_pattr { 1084*0Sstevel@tonic-gate dtrace_attribute_t dtpa_provider; /* provider attributes */ 1085*0Sstevel@tonic-gate dtrace_attribute_t dtpa_mod; /* module attributes */ 1086*0Sstevel@tonic-gate dtrace_attribute_t dtpa_func; /* function attributes */ 1087*0Sstevel@tonic-gate dtrace_attribute_t dtpa_name; /* name attributes */ 1088*0Sstevel@tonic-gate dtrace_attribute_t dtpa_args; /* args[] attributes */ 1089*0Sstevel@tonic-gate } dtrace_pattr_t; 1090*0Sstevel@tonic-gate 1091*0Sstevel@tonic-gate typedef struct dtrace_providerdesc { 1092*0Sstevel@tonic-gate char dtvd_name[DTRACE_PROVNAMELEN]; /* provider name */ 1093*0Sstevel@tonic-gate dtrace_pattr_t dtvd_attr; /* stability attributes */ 1094*0Sstevel@tonic-gate dtrace_ppriv_t dtvd_priv; /* privileges required */ 1095*0Sstevel@tonic-gate } dtrace_providerdesc_t; 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate /* 1098*0Sstevel@tonic-gate * DTrace Pseudodevice Interface 1099*0Sstevel@tonic-gate * 1100*0Sstevel@tonic-gate * DTrace is controlled through ioctl(2)'s to the in-kernel dtrace:dtrace 1101*0Sstevel@tonic-gate * pseudodevice driver. These ioctls comprise the user-kernel interface to 1102*0Sstevel@tonic-gate * DTrace. 1103*0Sstevel@tonic-gate */ 1104*0Sstevel@tonic-gate #define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) 1105*0Sstevel@tonic-gate #define DTRACEIOC_PROVIDER (DTRACEIOC | 1) /* provider query */ 1106*0Sstevel@tonic-gate #define DTRACEIOC_PROBES (DTRACEIOC | 2) /* probe query */ 1107*0Sstevel@tonic-gate #define DTRACEIOC_BUFSNAP (DTRACEIOC | 4) /* snapshot buffer */ 1108*0Sstevel@tonic-gate #define DTRACEIOC_PROBEMATCH (DTRACEIOC | 5) /* match probes */ 1109*0Sstevel@tonic-gate #define DTRACEIOC_ENABLE (DTRACEIOC | 6) /* enable probes */ 1110*0Sstevel@tonic-gate #define DTRACEIOC_AGGSNAP (DTRACEIOC | 7) /* snapshot agg. */ 1111*0Sstevel@tonic-gate #define DTRACEIOC_EPROBE (DTRACEIOC | 8) /* get eprobe desc. */ 1112*0Sstevel@tonic-gate #define DTRACEIOC_PROBEARG (DTRACEIOC | 9) /* get probe arg */ 1113*0Sstevel@tonic-gate #define DTRACEIOC_CONF (DTRACEIOC | 10) /* get config. */ 1114*0Sstevel@tonic-gate #define DTRACEIOC_STATUS (DTRACEIOC | 11) /* get status */ 1115*0Sstevel@tonic-gate #define DTRACEIOC_GO (DTRACEIOC | 12) /* start tracing */ 1116*0Sstevel@tonic-gate #define DTRACEIOC_STOP (DTRACEIOC | 13) /* stop tracing */ 1117*0Sstevel@tonic-gate #define DTRACEIOC_AGGDESC (DTRACEIOC | 15) /* get agg. desc. */ 1118*0Sstevel@tonic-gate #define DTRACEIOC_FORMAT (DTRACEIOC | 16) /* get format str */ 1119*0Sstevel@tonic-gate #define DTRACEIOC_DOFGET (DTRACEIOC | 17) /* get DOF */ 1120*0Sstevel@tonic-gate #define DTRACEIOC_REPLICATE (DTRACEIOC | 18) /* replicate enab */ 1121*0Sstevel@tonic-gate 1122*0Sstevel@tonic-gate /* 1123*0Sstevel@tonic-gate * DTrace Helpers 1124*0Sstevel@tonic-gate * 1125*0Sstevel@tonic-gate * In general, DTrace establishes probes in processes and takes actions on 1126*0Sstevel@tonic-gate * processes without knowing their specific user-level structures. Instead of 1127*0Sstevel@tonic-gate * existing in the framework, process-specific knowledge is contained by the 1128*0Sstevel@tonic-gate * enabling D program -- which can apply process-specific knowledge by making 1129*0Sstevel@tonic-gate * appropriate use of DTrace primitives like copyin() and copyinstr() to 1130*0Sstevel@tonic-gate * operate on user-level data. However, there may exist some specific probes 1131*0Sstevel@tonic-gate * of particular semantic relevance that the application developer may wish to 1132*0Sstevel@tonic-gate * explicitly export. For example, an application may wish to export a probe 1133*0Sstevel@tonic-gate * at the point that it begins and ends certain well-defined transactions. In 1134*0Sstevel@tonic-gate * addition to providing probes, programs may wish to offer assistance for 1135*0Sstevel@tonic-gate * certain actions. For example, in highly dynamic environments (e.g., Java), 1136*0Sstevel@tonic-gate * it may be difficult to obtain a stack trace in terms of meaningful symbol 1137*0Sstevel@tonic-gate * names (the translation from instruction addresses to corresponding symbol 1138*0Sstevel@tonic-gate * names may only be possible in situ); these environments may wish to define 1139*0Sstevel@tonic-gate * a series of actions to be applied in situ to obtain a meaningful stack 1140*0Sstevel@tonic-gate * trace. 1141*0Sstevel@tonic-gate * 1142*0Sstevel@tonic-gate * These two mechanisms -- user-level statically defined tracing and assisting 1143*0Sstevel@tonic-gate * DTrace actions -- are provided via DTrace _helpers_. Helpers are specified 1144*0Sstevel@tonic-gate * via DOF, but unlike enabling DOF, helper DOF may contain definitions of 1145*0Sstevel@tonic-gate * providers, probes and their arguments. If a helper wishes to provide 1146*0Sstevel@tonic-gate * action assistance, probe descriptions and corresponding DIF actions may be 1147*0Sstevel@tonic-gate * specified in the helper DOF. For such helper actions, however, the probe 1148*0Sstevel@tonic-gate * description describes the specific helper: all DTrace helpers have the 1149*0Sstevel@tonic-gate * provider name "dtrace" and the module name "helper", and the name of the 1150*0Sstevel@tonic-gate * helper is contained in the function name (for example, the ustack() helper 1151*0Sstevel@tonic-gate * is named "ustack"). Any helper-specific name may be contained in the name 1152*0Sstevel@tonic-gate * (for example, if a helper were to have a constructor, it might be named 1153*0Sstevel@tonic-gate * "dtrace:helper:<helper>:init"). Helper actions are only called when the 1154*0Sstevel@tonic-gate * action that they are helping is taken. Helper actions may only return DIF 1155*0Sstevel@tonic-gate * expressions, and may only call the following subroutines: 1156*0Sstevel@tonic-gate * 1157*0Sstevel@tonic-gate * alloca() <= Allocates memory out of the consumer's scratch space 1158*0Sstevel@tonic-gate * bcopy() <= Copies memory to scratch space 1159*0Sstevel@tonic-gate * copyin() <= Copies memory from user-level into consumer's scratch 1160*0Sstevel@tonic-gate * copyinto() <= Copies memory into a specific location in scratch 1161*0Sstevel@tonic-gate * copyinstr() <= Copies a string into a specific location in scratch 1162*0Sstevel@tonic-gate * 1163*0Sstevel@tonic-gate * Helper actions may only access the following built-in variables: 1164*0Sstevel@tonic-gate * 1165*0Sstevel@tonic-gate * curthread <= Current kthread_t pointer 1166*0Sstevel@tonic-gate * tid <= Current thread identifier 1167*0Sstevel@tonic-gate * pid <= Current process identifier 1168*0Sstevel@tonic-gate * execname <= Current executable name 1169*0Sstevel@tonic-gate * 1170*0Sstevel@tonic-gate * Helper actions may not manipulate or allocate dynamic variables, but they 1171*0Sstevel@tonic-gate * may have clause-local and statically-allocated global variables. The 1172*0Sstevel@tonic-gate * helper action variable state is specific to the helper action -- variables 1173*0Sstevel@tonic-gate * used by the helper action may not be accessed outside of the helper 1174*0Sstevel@tonic-gate * action, and the helper action may not access variables that like outside 1175*0Sstevel@tonic-gate * of it. Helper actions may not load from kernel memory at-large; they are 1176*0Sstevel@tonic-gate * restricting to loading current user state (via copyin() and variants) and 1177*0Sstevel@tonic-gate * scratch space. As with probe enablings, helper actions are executed in 1178*0Sstevel@tonic-gate * program order. The result of the helper action is the result of the last 1179*0Sstevel@tonic-gate * executing helper expression. 1180*0Sstevel@tonic-gate * 1181*0Sstevel@tonic-gate * Helpers -- composed of either providers/probes or probes/actions (or both) 1182*0Sstevel@tonic-gate * -- are added by opening the "helper" minor node, and issuing an ioctl(2) 1183*0Sstevel@tonic-gate * (DTRACEHIOC_ADDDOF) that specifies the dof_helper_t structure. This 1184*0Sstevel@tonic-gate * encapsulates the name and base address of the user-level library or 1185*0Sstevel@tonic-gate * executable publishing the helpers and probes as well as the DOF that 1186*0Sstevel@tonic-gate * contains the definitions of those helpers and probes. 1187*0Sstevel@tonic-gate * 1188*0Sstevel@tonic-gate * The DTRACEHIOC_ADD and DTRACEHIOC_REMOVE are left in place for legacy 1189*0Sstevel@tonic-gate * helpers and should no longer be used. No other ioctls are valid on the 1190*0Sstevel@tonic-gate * helper minor node. 1191*0Sstevel@tonic-gate */ 1192*0Sstevel@tonic-gate #define DTRACEHIOC (('d' << 24) | ('t' << 16) | ('h' << 8)) 1193*0Sstevel@tonic-gate #define DTRACEHIOC_ADD (DTRACEHIOC | 1) /* add helper */ 1194*0Sstevel@tonic-gate #define DTRACEHIOC_REMOVE (DTRACEHIOC | 2) /* remove helper */ 1195*0Sstevel@tonic-gate #define DTRACEHIOC_ADDDOF (DTRACEHIOC | 3) /* add helper DOF */ 1196*0Sstevel@tonic-gate 1197*0Sstevel@tonic-gate typedef struct dof_helper { 1198*0Sstevel@tonic-gate char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ 1199*0Sstevel@tonic-gate uint64_t dofhp_addr; /* base address of object */ 1200*0Sstevel@tonic-gate uint64_t dofhp_dof; /* address of helper DOF */ 1201*0Sstevel@tonic-gate } dof_helper_t; 1202*0Sstevel@tonic-gate 1203*0Sstevel@tonic-gate #define DTRACEMNR_DTRACE "dtrace" /* node for DTrace ops */ 1204*0Sstevel@tonic-gate #define DTRACEMNR_HELPER "helper" /* node for helpers */ 1205*0Sstevel@tonic-gate #define DTRACEMNRN_DTRACE 0 /* minor for DTrace ops */ 1206*0Sstevel@tonic-gate #define DTRACEMNRN_HELPER 1 /* minor for helpers */ 1207*0Sstevel@tonic-gate #define DTRACEMNRN_CLONE 2 /* first clone minor */ 1208*0Sstevel@tonic-gate 1209*0Sstevel@tonic-gate #ifdef _KERNEL 1210*0Sstevel@tonic-gate 1211*0Sstevel@tonic-gate /* 1212*0Sstevel@tonic-gate * DTrace Provider API 1213*0Sstevel@tonic-gate * 1214*0Sstevel@tonic-gate * The following functions are implemented by the DTrace framework and are 1215*0Sstevel@tonic-gate * used to implement separate in-kernel DTrace providers. Common functions 1216*0Sstevel@tonic-gate * are provided in uts/common/os/dtrace.c. ISA-dependent subroutines are 1217*0Sstevel@tonic-gate * defined in uts/<isa>/dtrace/dtrace_asm.s or uts/<isa>/dtrace/dtrace_isa.c. 1218*0Sstevel@tonic-gate * 1219*0Sstevel@tonic-gate * The provider API has two halves: the API that the providers consume from 1220*0Sstevel@tonic-gate * DTrace, and the API that providers make available to DTrace. 1221*0Sstevel@tonic-gate * 1222*0Sstevel@tonic-gate * 1 Framework-to-Provider API 1223*0Sstevel@tonic-gate * 1224*0Sstevel@tonic-gate * 1.1 Overview 1225*0Sstevel@tonic-gate * 1226*0Sstevel@tonic-gate * The Framework-to-Provider API is represented by the dtrace_pops structure 1227*0Sstevel@tonic-gate * that the provider passes to the framework when registering itself. This 1228*0Sstevel@tonic-gate * structure consists of the following members: 1229*0Sstevel@tonic-gate * 1230*0Sstevel@tonic-gate * dtps_provide() <-- Provide all probes, all modules 1231*0Sstevel@tonic-gate * dtps_provide_module() <-- Provide all probes in specified module 1232*0Sstevel@tonic-gate * dtps_enable() <-- Enable specified probe 1233*0Sstevel@tonic-gate * dtps_disable() <-- Disable specified probe 1234*0Sstevel@tonic-gate * dtps_suspend() <-- Suspend specified probe 1235*0Sstevel@tonic-gate * dtps_resume() <-- Resume specified probe 1236*0Sstevel@tonic-gate * dtps_getargdesc() <-- Get the argument description for args[X] 1237*0Sstevel@tonic-gate * dtps_getargval() <-- Get the value for an argX or args[X] variable 1238*0Sstevel@tonic-gate * dtps_usermode() <-- Find out if the probe was fired in user mode 1239*0Sstevel@tonic-gate * dtps_destroy() <-- Destroy all state associated with this probe 1240*0Sstevel@tonic-gate * 1241*0Sstevel@tonic-gate * 1.2 void dtps_provide(void *arg, const dtrace_probedesc_t *spec) 1242*0Sstevel@tonic-gate * 1243*0Sstevel@tonic-gate * 1.2.1 Overview 1244*0Sstevel@tonic-gate * 1245*0Sstevel@tonic-gate * Called to indicate that the provider should provide all probes. If the 1246*0Sstevel@tonic-gate * specified description is non-NULL, dtps_provide() is being called because 1247*0Sstevel@tonic-gate * no probe matched a specified probe -- if the provider has the ability to 1248*0Sstevel@tonic-gate * create custom probes, it may wish to create a probe that matches the 1249*0Sstevel@tonic-gate * specified description. 1250*0Sstevel@tonic-gate * 1251*0Sstevel@tonic-gate * 1.2.2 Arguments and notes 1252*0Sstevel@tonic-gate * 1253*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1254*0Sstevel@tonic-gate * second argument is a pointer to a probe description that the provider may 1255*0Sstevel@tonic-gate * wish to consider when creating custom probes. The provider is expected to 1256*0Sstevel@tonic-gate * call back into the DTrace framework via dtrace_probe_create() to create 1257*0Sstevel@tonic-gate * any necessary probes. dtps_provide() may be called even if the provider 1258*0Sstevel@tonic-gate * has made available all probes; the provider should check the return value 1259*0Sstevel@tonic-gate * of dtrace_probe_create() to handle this case. Note that the provider need 1260*0Sstevel@tonic-gate * not implement both dtps_provide() and dtps_provide_module(); see 1261*0Sstevel@tonic-gate * "Arguments and Notes" for dtrace_register(), below. 1262*0Sstevel@tonic-gate * 1263*0Sstevel@tonic-gate * 1.2.3 Return value 1264*0Sstevel@tonic-gate * 1265*0Sstevel@tonic-gate * None. 1266*0Sstevel@tonic-gate * 1267*0Sstevel@tonic-gate * 1.2.4 Caller's context 1268*0Sstevel@tonic-gate * 1269*0Sstevel@tonic-gate * dtps_provide() is typically called from open() or ioctl() context, but may 1270*0Sstevel@tonic-gate * be called from other contexts as well. The DTrace framework is locked in 1271*0Sstevel@tonic-gate * such a way that providers may not register or unregister. This means that 1272*0Sstevel@tonic-gate * the provider may not call any DTrace API that affects its registration with 1273*0Sstevel@tonic-gate * the framework, including dtrace_register(), dtrace_unregister(), 1274*0Sstevel@tonic-gate * dtrace_invalidate(), and dtrace_condense(). However, the context is such 1275*0Sstevel@tonic-gate * that the provider may (and indeed, is expected to) call probe-related 1276*0Sstevel@tonic-gate * DTrace routines, including dtrace_probe_create(), dtrace_probe_lookup(), 1277*0Sstevel@tonic-gate * and dtrace_probe_arg(). 1278*0Sstevel@tonic-gate * 1279*0Sstevel@tonic-gate * 1.3 void dtps_provide_module(void *arg, struct modctl *mp) 1280*0Sstevel@tonic-gate * 1281*0Sstevel@tonic-gate * 1.3.1 Overview 1282*0Sstevel@tonic-gate * 1283*0Sstevel@tonic-gate * Called to indicate that the provider should provide all probes in the 1284*0Sstevel@tonic-gate * specified module. 1285*0Sstevel@tonic-gate * 1286*0Sstevel@tonic-gate * 1.3.2 Arguments and notes 1287*0Sstevel@tonic-gate * 1288*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1289*0Sstevel@tonic-gate * second argument is a pointer to a modctl structure that indicates the 1290*0Sstevel@tonic-gate * module for which probes should be created. 1291*0Sstevel@tonic-gate * 1292*0Sstevel@tonic-gate * 1.3.3 Return value 1293*0Sstevel@tonic-gate * 1294*0Sstevel@tonic-gate * None. 1295*0Sstevel@tonic-gate * 1296*0Sstevel@tonic-gate * 1.3.4 Caller's context 1297*0Sstevel@tonic-gate * 1298*0Sstevel@tonic-gate * dtps_provide_module() may be called from open() or ioctl() context, but 1299*0Sstevel@tonic-gate * may also be called from a module loading context. mod_lock is held, and 1300*0Sstevel@tonic-gate * the DTrace framework is locked in such a way that providers may not 1301*0Sstevel@tonic-gate * register or unregister. This means that the provider may not call any 1302*0Sstevel@tonic-gate * DTrace API that affects its registration with the framework, including 1303*0Sstevel@tonic-gate * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 1304*0Sstevel@tonic-gate * dtrace_condense(). However, the context is such that the provider may (and 1305*0Sstevel@tonic-gate * indeed, is expected to) call probe-related DTrace routines, including 1306*0Sstevel@tonic-gate * dtrace_probe_create(), dtrace_probe_lookup(), and dtrace_probe_arg(). Note 1307*0Sstevel@tonic-gate * that the provider need not implement both dtps_provide() and 1308*0Sstevel@tonic-gate * dtps_provide_module(); see "Arguments and Notes" for dtrace_register(), 1309*0Sstevel@tonic-gate * below. 1310*0Sstevel@tonic-gate * 1311*0Sstevel@tonic-gate * 1.4 void dtps_enable(void *arg, dtrace_id_t id, void *parg) 1312*0Sstevel@tonic-gate * 1313*0Sstevel@tonic-gate * 1.4.1 Overview 1314*0Sstevel@tonic-gate * 1315*0Sstevel@tonic-gate * Called to enable the specified probe. 1316*0Sstevel@tonic-gate * 1317*0Sstevel@tonic-gate * 1.4.2 Arguments and notes 1318*0Sstevel@tonic-gate * 1319*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1320*0Sstevel@tonic-gate * second argument is the identifier of the probe to be enabled. The third 1321*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). 1322*0Sstevel@tonic-gate * dtps_enable() will be called when a probe transitions from not being 1323*0Sstevel@tonic-gate * enabled at all to having one or more ECB. The number of ECBs associated 1324*0Sstevel@tonic-gate * with the probe may change without subsequent calls into the provider. 1325*0Sstevel@tonic-gate * When the number of ECBs drops to zero, the provider will be explicitly 1326*0Sstevel@tonic-gate * told to disable the probe via dtps_disable(). dtrace_probe() should never 1327*0Sstevel@tonic-gate * be called for a probe identifier that hasn't been explicitly enabled via 1328*0Sstevel@tonic-gate * dtps_enable(). 1329*0Sstevel@tonic-gate * 1330*0Sstevel@tonic-gate * 1.4.3 Return value 1331*0Sstevel@tonic-gate * 1332*0Sstevel@tonic-gate * None. 1333*0Sstevel@tonic-gate * 1334*0Sstevel@tonic-gate * 1.4.4 Caller's context 1335*0Sstevel@tonic-gate * 1336*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that it may not be called 1337*0Sstevel@tonic-gate * back into at all. cpu_lock is held. mod_lock is not held and may not 1338*0Sstevel@tonic-gate * be acquired. 1339*0Sstevel@tonic-gate * 1340*0Sstevel@tonic-gate * 1.5 void dtps_disable(void *arg, dtrace_id_t id, void *parg) 1341*0Sstevel@tonic-gate * 1342*0Sstevel@tonic-gate * 1.5.1 Overview 1343*0Sstevel@tonic-gate * 1344*0Sstevel@tonic-gate * Called to disable the specified probe. 1345*0Sstevel@tonic-gate * 1346*0Sstevel@tonic-gate * 1.5.2 Arguments and notes 1347*0Sstevel@tonic-gate * 1348*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1349*0Sstevel@tonic-gate * second argument is the identifier of the probe to be disabled. The third 1350*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). 1351*0Sstevel@tonic-gate * dtps_disable() will be called when a probe transitions from being enabled 1352*0Sstevel@tonic-gate * to having zero ECBs. dtrace_probe() should never be called for a probe 1353*0Sstevel@tonic-gate * identifier that has been explicitly enabled via dtps_disable(). 1354*0Sstevel@tonic-gate * 1355*0Sstevel@tonic-gate * 1.5.3 Return value 1356*0Sstevel@tonic-gate * 1357*0Sstevel@tonic-gate * None. 1358*0Sstevel@tonic-gate * 1359*0Sstevel@tonic-gate * 1.5.4 Caller's context 1360*0Sstevel@tonic-gate * 1361*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that it may not be called 1362*0Sstevel@tonic-gate * back into at all. cpu_lock is held. mod_lock is not held and may not 1363*0Sstevel@tonic-gate * be acquired. 1364*0Sstevel@tonic-gate * 1365*0Sstevel@tonic-gate * 1.6 void dtps_suspend(void *arg, dtrace_id_t id, void *parg) 1366*0Sstevel@tonic-gate * 1367*0Sstevel@tonic-gate * 1.6.1 Overview 1368*0Sstevel@tonic-gate * 1369*0Sstevel@tonic-gate * Called to suspend the specified enabled probe. This entry point is for 1370*0Sstevel@tonic-gate * providers that may need to suspend some or all of their probes when CPUs 1371*0Sstevel@tonic-gate * are being powered on or when the boot monitor is being entered for a 1372*0Sstevel@tonic-gate * prolonged period of time. 1373*0Sstevel@tonic-gate * 1374*0Sstevel@tonic-gate * 1.6.2 Arguments and notes 1375*0Sstevel@tonic-gate * 1376*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1377*0Sstevel@tonic-gate * second argument is the identifier of the probe to be suspended. The 1378*0Sstevel@tonic-gate * third argument is the probe argument as passed to dtrace_probe_create(). 1379*0Sstevel@tonic-gate * dtps_suspend will only be called on an enabled probe. Providers that 1380*0Sstevel@tonic-gate * provide a dtps_suspend entry point will want to take roughly the action 1381*0Sstevel@tonic-gate * that it takes for dtps_disable. 1382*0Sstevel@tonic-gate * 1383*0Sstevel@tonic-gate * 1.6.3 Return value 1384*0Sstevel@tonic-gate * 1385*0Sstevel@tonic-gate * None. 1386*0Sstevel@tonic-gate * 1387*0Sstevel@tonic-gate * 1.6.4 Caller's context 1388*0Sstevel@tonic-gate * 1389*0Sstevel@tonic-gate * Interrupts are disabled. The DTrace framework is in a state such that the 1390*0Sstevel@tonic-gate * specified probe cannot be disabled or destroyed for the duration of 1391*0Sstevel@tonic-gate * dtps_suspend(). As interrupts are disabled, the provider is afforded 1392*0Sstevel@tonic-gate * little latitude; the provider is expected to do no more than a store to 1393*0Sstevel@tonic-gate * memory. 1394*0Sstevel@tonic-gate * 1395*0Sstevel@tonic-gate * 1.7 void dtps_resume(void *arg, dtrace_id_t id, void *parg) 1396*0Sstevel@tonic-gate * 1397*0Sstevel@tonic-gate * 1.7.1 Overview 1398*0Sstevel@tonic-gate * 1399*0Sstevel@tonic-gate * Called to resume the specified enabled probe. This entry point is for 1400*0Sstevel@tonic-gate * providers that may need to resume some or all of their probes after the 1401*0Sstevel@tonic-gate * completion of an event that induced a call to dtps_suspend(). 1402*0Sstevel@tonic-gate * 1403*0Sstevel@tonic-gate * 1.7.2 Arguments and notes 1404*0Sstevel@tonic-gate * 1405*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1406*0Sstevel@tonic-gate * second argument is the identifier of the probe to be resumed. The 1407*0Sstevel@tonic-gate * third argument is the probe argument as passed to dtrace_probe_create(). 1408*0Sstevel@tonic-gate * dtps_resume will only be called on an enabled probe. Providers that 1409*0Sstevel@tonic-gate * provide a dtps_resume entry point will want to take roughly the action 1410*0Sstevel@tonic-gate * that it takes for dtps_enable. 1411*0Sstevel@tonic-gate * 1412*0Sstevel@tonic-gate * 1.7.3 Return value 1413*0Sstevel@tonic-gate * 1414*0Sstevel@tonic-gate * None. 1415*0Sstevel@tonic-gate * 1416*0Sstevel@tonic-gate * 1.7.4 Caller's context 1417*0Sstevel@tonic-gate * 1418*0Sstevel@tonic-gate * Interrupts are disabled. The DTrace framework is in a state such that the 1419*0Sstevel@tonic-gate * specified probe cannot be disabled or destroyed for the duration of 1420*0Sstevel@tonic-gate * dtps_resume(). As interrupts are disabled, the provider is afforded 1421*0Sstevel@tonic-gate * little latitude; the provider is expected to do no more than a store to 1422*0Sstevel@tonic-gate * memory. 1423*0Sstevel@tonic-gate * 1424*0Sstevel@tonic-gate * 1.8 void dtps_getargdesc(void *arg, dtrace_id_t id, void *parg, 1425*0Sstevel@tonic-gate * dtrace_argdesc_t *desc) 1426*0Sstevel@tonic-gate * 1427*0Sstevel@tonic-gate * 1.8.1 Overview 1428*0Sstevel@tonic-gate * 1429*0Sstevel@tonic-gate * Called to retrieve the argument description for an args[X] variable. 1430*0Sstevel@tonic-gate * 1431*0Sstevel@tonic-gate * 1.8.2 Arguments and notes 1432*0Sstevel@tonic-gate * 1433*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1434*0Sstevel@tonic-gate * second argument is the identifier of the current probe. The third 1435*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). The 1436*0Sstevel@tonic-gate * fourth argument is a pointer to the argument description. This 1437*0Sstevel@tonic-gate * description is both an input and output parameter: it contains the 1438*0Sstevel@tonic-gate * index of the desired argument in the dtargd_ndx field, and expects 1439*0Sstevel@tonic-gate * the other fields to be filled in upon return. If there is no argument 1440*0Sstevel@tonic-gate * corresponding to the specified index, the dtargd_ndx field should be set 1441*0Sstevel@tonic-gate * to DTRACE_ARGNONE. 1442*0Sstevel@tonic-gate * 1443*0Sstevel@tonic-gate * 1.8.3 Return value 1444*0Sstevel@tonic-gate * 1445*0Sstevel@tonic-gate * None. The dtargd_ndx, dtargd_native, dtargd_xlate and dtargd_mapping 1446*0Sstevel@tonic-gate * members of the dtrace_argdesc_t structure are all output values. 1447*0Sstevel@tonic-gate * 1448*0Sstevel@tonic-gate * 1.8.4 Caller's context 1449*0Sstevel@tonic-gate * 1450*0Sstevel@tonic-gate * dtps_getargdesc() is called from ioctl() context. mod_lock is held, and 1451*0Sstevel@tonic-gate * the DTrace framework is locked in such a way that providers may not 1452*0Sstevel@tonic-gate * register or unregister. This means that the provider may not call any 1453*0Sstevel@tonic-gate * DTrace API that affects its registration with the framework, including 1454*0Sstevel@tonic-gate * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 1455*0Sstevel@tonic-gate * dtrace_condense(). 1456*0Sstevel@tonic-gate * 1457*0Sstevel@tonic-gate * 1.9 uint64_t dtps_getargval(void *arg, dtrace_id_t id, void *parg, 1458*0Sstevel@tonic-gate * int argno, int aframes) 1459*0Sstevel@tonic-gate * 1460*0Sstevel@tonic-gate * 1.9.1 Overview 1461*0Sstevel@tonic-gate * 1462*0Sstevel@tonic-gate * Called to retrieve a value for an argX or args[X] variable. 1463*0Sstevel@tonic-gate * 1464*0Sstevel@tonic-gate * 1.9.2 Arguments and notes 1465*0Sstevel@tonic-gate * 1466*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1467*0Sstevel@tonic-gate * second argument is the identifier of the current probe. The third 1468*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). The 1469*0Sstevel@tonic-gate * fourth argument is the number of the argument (the X in the example in 1470*0Sstevel@tonic-gate * 1.9.1). The fifth argument is the number of stack frames that were used 1471*0Sstevel@tonic-gate * to get from the actual place in the code that fired the probe to 1472*0Sstevel@tonic-gate * dtrace_probe() itself, the so-called artificial frames. This argument may 1473*0Sstevel@tonic-gate * be used to descend an appropriate number of frames to find the correct 1474*0Sstevel@tonic-gate * values. If this entry point is left NULL, the dtrace_getarg() built-in 1475*0Sstevel@tonic-gate * function is used. 1476*0Sstevel@tonic-gate * 1477*0Sstevel@tonic-gate * 1.9.3 Return value 1478*0Sstevel@tonic-gate * 1479*0Sstevel@tonic-gate * The value of the argument. 1480*0Sstevel@tonic-gate * 1481*0Sstevel@tonic-gate * 1.9.4 Caller's context 1482*0Sstevel@tonic-gate * 1483*0Sstevel@tonic-gate * This is called from within dtrace_probe() meaning that interrupts 1484*0Sstevel@tonic-gate * are disabled. No locks should be taken within this entry point. 1485*0Sstevel@tonic-gate * 1486*0Sstevel@tonic-gate * 1.10 int dtps_usermode(void *arg, dtrace_id_t id, void *parg) 1487*0Sstevel@tonic-gate * 1488*0Sstevel@tonic-gate * 1.10.1 Overview 1489*0Sstevel@tonic-gate * 1490*0Sstevel@tonic-gate * Called to determine if the probe was fired in a user context. 1491*0Sstevel@tonic-gate * 1492*0Sstevel@tonic-gate * 1.10.2 Arguments and notes 1493*0Sstevel@tonic-gate * 1494*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1495*0Sstevel@tonic-gate * second argument is the identifier of the current probe. The third 1496*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). This 1497*0Sstevel@tonic-gate * entry point must not be left NULL for providers whose probes allow for 1498*0Sstevel@tonic-gate * mixed mode tracing, that is to say those probes that can fire during 1499*0Sstevel@tonic-gate * kernel- _or_ user-mode execution 1500*0Sstevel@tonic-gate * 1501*0Sstevel@tonic-gate * 1.10.3 Return value 1502*0Sstevel@tonic-gate * 1503*0Sstevel@tonic-gate * A boolean value. 1504*0Sstevel@tonic-gate * 1505*0Sstevel@tonic-gate * 1.10.4 Caller's context 1506*0Sstevel@tonic-gate * 1507*0Sstevel@tonic-gate * This is called from within dtrace_probe() meaning that interrupts 1508*0Sstevel@tonic-gate * are disabled. No locks should be taken within this entry point. 1509*0Sstevel@tonic-gate * 1510*0Sstevel@tonic-gate * 1.11 void dtps_destroy(void *arg, dtrace_id_t id, void *parg) 1511*0Sstevel@tonic-gate * 1512*0Sstevel@tonic-gate * 1.11.1 Overview 1513*0Sstevel@tonic-gate * 1514*0Sstevel@tonic-gate * Called to destroy the specified probe. 1515*0Sstevel@tonic-gate * 1516*0Sstevel@tonic-gate * 1.11.2 Arguments and notes 1517*0Sstevel@tonic-gate * 1518*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_register(). The 1519*0Sstevel@tonic-gate * second argument is the identifier of the probe to be destroyed. The third 1520*0Sstevel@tonic-gate * argument is the probe argument as passed to dtrace_probe_create(). The 1521*0Sstevel@tonic-gate * provider should free all state associated with the probe. The framework 1522*0Sstevel@tonic-gate * guarantees that dtps_destroy() is only called for probes that have either 1523*0Sstevel@tonic-gate * been disabled via dtps_disable() or were never enabled via dtps_enable(). 1524*0Sstevel@tonic-gate * Once dtps_disable() has been called for a probe, no further call will be 1525*0Sstevel@tonic-gate * made specifying the probe. 1526*0Sstevel@tonic-gate * 1527*0Sstevel@tonic-gate * 1.11.3 Return value 1528*0Sstevel@tonic-gate * 1529*0Sstevel@tonic-gate * None. 1530*0Sstevel@tonic-gate * 1531*0Sstevel@tonic-gate * 1.11.4 Caller's context 1532*0Sstevel@tonic-gate * 1533*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that it may not be called 1534*0Sstevel@tonic-gate * back into at all. mod_lock is held. cpu_lock is not held, and may not be 1535*0Sstevel@tonic-gate * acquired. 1536*0Sstevel@tonic-gate * 1537*0Sstevel@tonic-gate * 1538*0Sstevel@tonic-gate * 2 Provider-to-Framework API 1539*0Sstevel@tonic-gate * 1540*0Sstevel@tonic-gate * 2.1 Overview 1541*0Sstevel@tonic-gate * 1542*0Sstevel@tonic-gate * The Provider-to-Framework API provides the mechanism for the provider to 1543*0Sstevel@tonic-gate * register itself with the DTrace framework, to create probes, to lookup 1544*0Sstevel@tonic-gate * probes and (most importantly) to fire probes. The Provider-to-Framework 1545*0Sstevel@tonic-gate * consists of: 1546*0Sstevel@tonic-gate * 1547*0Sstevel@tonic-gate * dtrace_register() <-- Register a provider with the DTrace framework 1548*0Sstevel@tonic-gate * dtrace_unregister() <-- Remove a provider's DTrace registration 1549*0Sstevel@tonic-gate * dtrace_invalidate() <-- Invalidate the specified provider 1550*0Sstevel@tonic-gate * dtrace_condense() <-- Remove a provider's unenabled probes 1551*0Sstevel@tonic-gate * dtrace_attached() <-- Indicates whether or not DTrace has attached 1552*0Sstevel@tonic-gate * dtrace_probe_create() <-- Create a DTrace probe 1553*0Sstevel@tonic-gate * dtrace_probe_lookup() <-- Lookup a DTrace probe based on its name 1554*0Sstevel@tonic-gate * dtrace_probe_arg() <-- Return the probe argument for a specific probe 1555*0Sstevel@tonic-gate * dtrace_probe() <-- Fire the specified probe 1556*0Sstevel@tonic-gate * 1557*0Sstevel@tonic-gate * 2.2 int dtrace_register(const char *name, const dtrace_pattr_t *pap, 1558*0Sstevel@tonic-gate * uint32_t priv, uid_t uid, const dtrace_pops_t *pops, void *arg, 1559*0Sstevel@tonic-gate * dtrace_provider_id_t *idp) 1560*0Sstevel@tonic-gate * 1561*0Sstevel@tonic-gate * 2.2.1 Overview 1562*0Sstevel@tonic-gate * 1563*0Sstevel@tonic-gate * dtrace_register() registers the calling provider with the DTrace 1564*0Sstevel@tonic-gate * framework. It should generally be called by DTrace providers in their 1565*0Sstevel@tonic-gate * attach(9E) entry point. 1566*0Sstevel@tonic-gate * 1567*0Sstevel@tonic-gate * 2.2.2 Arguments and Notes 1568*0Sstevel@tonic-gate * 1569*0Sstevel@tonic-gate * The first argument is the name of the provider. The second argument is a 1570*0Sstevel@tonic-gate * pointer to the stability attributes for the provider. The third argument 1571*0Sstevel@tonic-gate * is the privilege flags for the provider, and must be some combination of: 1572*0Sstevel@tonic-gate * 1573*0Sstevel@tonic-gate * DTRACE_PRIV_NONE <= All users may enable probes from this provider 1574*0Sstevel@tonic-gate * 1575*0Sstevel@tonic-gate * DTRACE_PRIV_PROC <= Any user with privilege of PRIV_DTRACE_PROC may 1576*0Sstevel@tonic-gate * enable probes from this provider 1577*0Sstevel@tonic-gate * 1578*0Sstevel@tonic-gate * DTRACE_PRIV_USER <= Any user with privilege of PRIV_DTRACE_USER may 1579*0Sstevel@tonic-gate * enable probes from this provider 1580*0Sstevel@tonic-gate * 1581*0Sstevel@tonic-gate * DTRACE_PRIV_KERNEL <= Any user with privilege of PRIV_DTRACE_KERNEL 1582*0Sstevel@tonic-gate * may enable probes from this provider 1583*0Sstevel@tonic-gate * 1584*0Sstevel@tonic-gate * DTRACE_PRIV_OWNER <= This flag places an additional constraint on 1585*0Sstevel@tonic-gate * the privilege requirements above. These probes 1586*0Sstevel@tonic-gate * require either (a) a user ID matching the user 1587*0Sstevel@tonic-gate * ID passed as the fourth argument to 1588*0Sstevel@tonic-gate * dtrace_register() or (b) the PRIV_PROC_OWNER 1589*0Sstevel@tonic-gate * privilege. 1590*0Sstevel@tonic-gate * 1591*0Sstevel@tonic-gate * Note that these flags designate the _visibility_ of the probes, not 1592*0Sstevel@tonic-gate * the conditions under which they may or may not fire. 1593*0Sstevel@tonic-gate * 1594*0Sstevel@tonic-gate * The fourth argument is a user ID that is associated with the provider. 1595*0Sstevel@tonic-gate * This argument should be 0 if the privilege flags don't include 1596*0Sstevel@tonic-gate * DTRACE_PRIV_OWNER. 1597*0Sstevel@tonic-gate * 1598*0Sstevel@tonic-gate * The fifth argument is a DTrace provider operations vector, which provides 1599*0Sstevel@tonic-gate * the implementation for the Framework-to-Provider API. (See Section 1, 1600*0Sstevel@tonic-gate * above.) This must be non-NULL, and each member must be non-NULL. The 1601*0Sstevel@tonic-gate * exceptions to this are (1) the dtps_provide() and dtps_provide_module() 1602*0Sstevel@tonic-gate * members (if the provider so desires, _one_ of these members may be left 1603*0Sstevel@tonic-gate * NULL -- denoting that the provider only implements the other) and (2) 1604*0Sstevel@tonic-gate * the dtps_suspend() and dtps_resume() members, which must either both be 1605*0Sstevel@tonic-gate * NULL or both be non-NULL. 1606*0Sstevel@tonic-gate * 1607*0Sstevel@tonic-gate * The sixth argument is a cookie to be specified as the first argument for 1608*0Sstevel@tonic-gate * each function in the Framework-to-Provider API. This argument may have 1609*0Sstevel@tonic-gate * any value. 1610*0Sstevel@tonic-gate * 1611*0Sstevel@tonic-gate * The final argument is a pointer to dtrace_provider_id_t. If 1612*0Sstevel@tonic-gate * dtrace_register() successfully completes, the provider identifier will be 1613*0Sstevel@tonic-gate * stored in the memory pointed to be this argument. This argument must be 1614*0Sstevel@tonic-gate * non-NULL. 1615*0Sstevel@tonic-gate * 1616*0Sstevel@tonic-gate * 2.2.3 Return value 1617*0Sstevel@tonic-gate * 1618*0Sstevel@tonic-gate * On success, dtrace_register() returns 0 and stores the new provider's 1619*0Sstevel@tonic-gate * identifier into the memory pointed to by the idp argument. On failure, 1620*0Sstevel@tonic-gate * dtrace_register() returns an errno: 1621*0Sstevel@tonic-gate * 1622*0Sstevel@tonic-gate * EINVAL The arguments passed to dtrace_register() were somehow invalid. 1623*0Sstevel@tonic-gate * This may because a parameter that must be non-NULL was NULL, 1624*0Sstevel@tonic-gate * because the name was invalid (either empty or an illegal 1625*0Sstevel@tonic-gate * provider name) or because the attributes were invalid. 1626*0Sstevel@tonic-gate * 1627*0Sstevel@tonic-gate * No other failure code is returned. 1628*0Sstevel@tonic-gate * 1629*0Sstevel@tonic-gate * 2.2.4 Caller's context 1630*0Sstevel@tonic-gate * 1631*0Sstevel@tonic-gate * dtrace_register() may induce calls to dtrace_provide(); the provider must 1632*0Sstevel@tonic-gate * hold no locks across dtrace_register() that may also be acquired by 1633*0Sstevel@tonic-gate * dtrace_provide(). cpu_lock and mod_lock must not be held. 1634*0Sstevel@tonic-gate * 1635*0Sstevel@tonic-gate * 2.3 int dtrace_unregister(dtrace_provider_t id) 1636*0Sstevel@tonic-gate * 1637*0Sstevel@tonic-gate * 2.3.1 Overview 1638*0Sstevel@tonic-gate * 1639*0Sstevel@tonic-gate * Unregisters the specified provider from the DTrace framework. It should 1640*0Sstevel@tonic-gate * generally be called by DTrace providers in their detach(9E) entry point. 1641*0Sstevel@tonic-gate * 1642*0Sstevel@tonic-gate * 2.3.2 Arguments and Notes 1643*0Sstevel@tonic-gate * 1644*0Sstevel@tonic-gate * The only argument is the provider identifier, as returned from a 1645*0Sstevel@tonic-gate * successful call to dtrace_register(). As a result of calling 1646*0Sstevel@tonic-gate * dtrace_unregister(), the DTrace framework will call back into the provider 1647*0Sstevel@tonic-gate * via the dtps_destroy() entry point. Once dtrace_unregister() successfully 1648*0Sstevel@tonic-gate * completes, however, the DTrace framework will no longer make calls through 1649*0Sstevel@tonic-gate * the Framework-to-Provider API. 1650*0Sstevel@tonic-gate * 1651*0Sstevel@tonic-gate * 2.3.3 Return value 1652*0Sstevel@tonic-gate * 1653*0Sstevel@tonic-gate * On success, dtrace_unregister returns 0. On failure, dtrace_unregister() 1654*0Sstevel@tonic-gate * returns an errno: 1655*0Sstevel@tonic-gate * 1656*0Sstevel@tonic-gate * EBUSY There are currently processes that have the DTrace pseudodevice 1657*0Sstevel@tonic-gate * open, or there exists an anonymous enabling that hasn't yet 1658*0Sstevel@tonic-gate * been claimed. 1659*0Sstevel@tonic-gate * 1660*0Sstevel@tonic-gate * No other failure code is returned. 1661*0Sstevel@tonic-gate * 1662*0Sstevel@tonic-gate * 2.3.4 Caller's context 1663*0Sstevel@tonic-gate * 1664*0Sstevel@tonic-gate * Because a call to dtrace_unregister() may induce calls through the 1665*0Sstevel@tonic-gate * Framework-to-Provider API, the caller may not hold any lock across 1666*0Sstevel@tonic-gate * dtrace_register() that is also acquired in any of the Framework-to- 1667*0Sstevel@tonic-gate * Provider API functions. Additionally, mod_lock may not be held. 1668*0Sstevel@tonic-gate * 1669*0Sstevel@tonic-gate * 2.4 void dtrace_invalidate(dtrace_provider_id_t id) 1670*0Sstevel@tonic-gate * 1671*0Sstevel@tonic-gate * 2.4.1 Overview 1672*0Sstevel@tonic-gate * 1673*0Sstevel@tonic-gate * Invalidates the specified provider. All subsequent probe lookups for the 1674*0Sstevel@tonic-gate * specified provider will fail, but its probes will not be removed. 1675*0Sstevel@tonic-gate * 1676*0Sstevel@tonic-gate * 2.4.2 Arguments and note 1677*0Sstevel@tonic-gate * 1678*0Sstevel@tonic-gate * The only argument is the provider identifier, as returned from a 1679*0Sstevel@tonic-gate * successful call to dtrace_register(). In general, a provider's probes 1680*0Sstevel@tonic-gate * always remain valid; dtrace_invalidate() is a mechanism for invalidating 1681*0Sstevel@tonic-gate * an entire provider, regardless of whether or not probes are enabled or 1682*0Sstevel@tonic-gate * not. Note that dtrace_invalidate() will _not_ prevent already enabled 1683*0Sstevel@tonic-gate * probes from firing -- it will merely prevent any new enablings of the 1684*0Sstevel@tonic-gate * provider's probes. 1685*0Sstevel@tonic-gate * 1686*0Sstevel@tonic-gate * 2.5 int dtrace_condense(dtrace_provider_id_t id) 1687*0Sstevel@tonic-gate * 1688*0Sstevel@tonic-gate * 2.5.1 Overview 1689*0Sstevel@tonic-gate * 1690*0Sstevel@tonic-gate * Removes all the unenabled probes for the given provider. This function is 1691*0Sstevel@tonic-gate * not unlike dtrace_unregister(), except that it doesn't remove the 1692*0Sstevel@tonic-gate * provider just as many of its associated probes as it can. 1693*0Sstevel@tonic-gate * 1694*0Sstevel@tonic-gate * 2.5.2 Arguments and Notes 1695*0Sstevel@tonic-gate * 1696*0Sstevel@tonic-gate * As with dtrace_unregister(), the sole argument is the provider identifier 1697*0Sstevel@tonic-gate * as returned from a successful call to dtrace_register(). As a result of 1698*0Sstevel@tonic-gate * calling dtrace_condense(), the DTrace framework will call back into the 1699*0Sstevel@tonic-gate * given provider's dtps_destroy() entry point for each of the provider's 1700*0Sstevel@tonic-gate * unenabled probes. 1701*0Sstevel@tonic-gate * 1702*0Sstevel@tonic-gate * 2.5.3 Return value 1703*0Sstevel@tonic-gate * 1704*0Sstevel@tonic-gate * Currently, dtrace_condense() always returns 0. However, consumers of this 1705*0Sstevel@tonic-gate * function should check the return value as appropriate; its behavior may 1706*0Sstevel@tonic-gate * change in the future. 1707*0Sstevel@tonic-gate * 1708*0Sstevel@tonic-gate * 2.5.4 Caller's context 1709*0Sstevel@tonic-gate * 1710*0Sstevel@tonic-gate * As with dtrace_unregister(), the caller may not hold any lock across 1711*0Sstevel@tonic-gate * dtrace_condense() that is also acquired in the provider's entry points. 1712*0Sstevel@tonic-gate * Also, mod_lock may not be held. 1713*0Sstevel@tonic-gate * 1714*0Sstevel@tonic-gate * 2.6 int dtrace_attached() 1715*0Sstevel@tonic-gate * 1716*0Sstevel@tonic-gate * 2.6.1 Overview 1717*0Sstevel@tonic-gate * 1718*0Sstevel@tonic-gate * Indicates whether or not DTrace has attached. 1719*0Sstevel@tonic-gate * 1720*0Sstevel@tonic-gate * 2.6.2 Arguments and Notes 1721*0Sstevel@tonic-gate * 1722*0Sstevel@tonic-gate * For most providers, DTrace makes initial contact beyond registration. 1723*0Sstevel@tonic-gate * That is, once a provider has registered with DTrace, it waits to hear 1724*0Sstevel@tonic-gate * from DTrace to create probes. However, some providers may wish to 1725*0Sstevel@tonic-gate * proactively create probes without first being told by DTrace to do so. 1726*0Sstevel@tonic-gate * If providers wish to do this, they must first call dtrace_attached() to 1727*0Sstevel@tonic-gate * determine if DTrace itself has attached. If dtrace_attached() returns 0, 1728*0Sstevel@tonic-gate * the provider must not make any other Provider-to-Framework API call. 1729*0Sstevel@tonic-gate * 1730*0Sstevel@tonic-gate * 2.6.3 Return value 1731*0Sstevel@tonic-gate * 1732*0Sstevel@tonic-gate * dtrace_attached() returns 1 if DTrace has attached, 0 otherwise. 1733*0Sstevel@tonic-gate * 1734*0Sstevel@tonic-gate * 2.7 int dtrace_probe_create(dtrace_provider_t id, const char *mod, 1735*0Sstevel@tonic-gate * const char *func, const char *name, int aframes, void *arg) 1736*0Sstevel@tonic-gate * 1737*0Sstevel@tonic-gate * 2.7.1 Overview 1738*0Sstevel@tonic-gate * 1739*0Sstevel@tonic-gate * Creates a probe with specified module name, function name, and name. 1740*0Sstevel@tonic-gate * 1741*0Sstevel@tonic-gate * 2.7.2 Arguments and Notes 1742*0Sstevel@tonic-gate * 1743*0Sstevel@tonic-gate * The first argument is the provider identifier, as returned from a 1744*0Sstevel@tonic-gate * successful call to dtrace_register(). The second, third, and fourth 1745*0Sstevel@tonic-gate * arguments are the module name, function name, and probe name, 1746*0Sstevel@tonic-gate * respectively. Of these, module name and function name may both be NULL 1747*0Sstevel@tonic-gate * (in which case the probe is considered to be unanchored), or they may both 1748*0Sstevel@tonic-gate * be non-NULL. The name must be non-NULL, and must point to a non-empty 1749*0Sstevel@tonic-gate * string. 1750*0Sstevel@tonic-gate * 1751*0Sstevel@tonic-gate * The fifth argument is the number of artificial stack frames that will be 1752*0Sstevel@tonic-gate * found on the stack when dtrace_probe() is called for the new probe. These 1753*0Sstevel@tonic-gate * artificial frames will be automatically be pruned should the stack() or 1754*0Sstevel@tonic-gate * stackdepth() functions be called as part of one of the probe's ECBs. If 1755*0Sstevel@tonic-gate * the parameter doesn't add an artificial frame, this parameter should be 1756*0Sstevel@tonic-gate * zero. 1757*0Sstevel@tonic-gate * 1758*0Sstevel@tonic-gate * The final argument is a probe argument that will be passed back to the 1759*0Sstevel@tonic-gate * provider when a probe-specific operation is called. (e.g., via 1760*0Sstevel@tonic-gate * dtps_enable(), dtps_disable(), etc.) 1761*0Sstevel@tonic-gate * 1762*0Sstevel@tonic-gate * Note that it is up to the provider to be sure that the probe that it 1763*0Sstevel@tonic-gate * creates does not already exist -- if the provider is unsure of the probe's 1764*0Sstevel@tonic-gate * existence, it should assure its absence with dtrace_probe_lookup() before 1765*0Sstevel@tonic-gate * calling dtrace_probe_create(). 1766*0Sstevel@tonic-gate * 1767*0Sstevel@tonic-gate * 2.7.3 Return value 1768*0Sstevel@tonic-gate * 1769*0Sstevel@tonic-gate * dtrace_probe_create() always succeeds, and always returns the identifier 1770*0Sstevel@tonic-gate * of the newly-created probe. 1771*0Sstevel@tonic-gate * 1772*0Sstevel@tonic-gate * 2.7.4 Caller's context 1773*0Sstevel@tonic-gate * 1774*0Sstevel@tonic-gate * While dtrace_probe_create() is generally expected to be called from 1775*0Sstevel@tonic-gate * dtps_provide() and/or dtps_provide_module(), it may be called from other 1776*0Sstevel@tonic-gate * non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1777*0Sstevel@tonic-gate * 1778*0Sstevel@tonic-gate * 2.8 dtrace_id_t dtrace_probe_lookup(dtrace_provider_t id, const char *mod, 1779*0Sstevel@tonic-gate * const char *func, const char *name) 1780*0Sstevel@tonic-gate * 1781*0Sstevel@tonic-gate * 2.8.1 Overview 1782*0Sstevel@tonic-gate * 1783*0Sstevel@tonic-gate * Looks up a probe based on provdider and one or more of module name, 1784*0Sstevel@tonic-gate * function name and probe name. 1785*0Sstevel@tonic-gate * 1786*0Sstevel@tonic-gate * 2.8.2 Arguments and Notes 1787*0Sstevel@tonic-gate * 1788*0Sstevel@tonic-gate * The first argument is the provider identifier, as returned from a 1789*0Sstevel@tonic-gate * successful call to dtrace_register(). The second, third, and fourth 1790*0Sstevel@tonic-gate * arguments are the module name, function name, and probe name, 1791*0Sstevel@tonic-gate * respectively. Any of these may be NULL; dtrace_probe_lookup() will return 1792*0Sstevel@tonic-gate * the identifier of the first probe that is provided by the specified 1793*0Sstevel@tonic-gate * provider and matches all of the non-NULL matching criteria. 1794*0Sstevel@tonic-gate * dtrace_probe_lookup() is generally used by a provider to be check the 1795*0Sstevel@tonic-gate * existence of a probe before creating it with dtrace_probe_create(). 1796*0Sstevel@tonic-gate * 1797*0Sstevel@tonic-gate * 2.8.3 Return value 1798*0Sstevel@tonic-gate * 1799*0Sstevel@tonic-gate * If the probe exists, returns its identifier. If the probe does not exist, 1800*0Sstevel@tonic-gate * return DTRACE_IDNONE. 1801*0Sstevel@tonic-gate * 1802*0Sstevel@tonic-gate * 2.8.4 Caller's context 1803*0Sstevel@tonic-gate * 1804*0Sstevel@tonic-gate * While dtrace_probe_lookup() is generally expected to be called from 1805*0Sstevel@tonic-gate * dtps_provide() and/or dtps_provide_module(), it may also be called from 1806*0Sstevel@tonic-gate * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1807*0Sstevel@tonic-gate * 1808*0Sstevel@tonic-gate * 2.9 void *dtrace_probe_arg(dtrace_provider_t id, dtrace_id_t probe) 1809*0Sstevel@tonic-gate * 1810*0Sstevel@tonic-gate * 2.9.1 Overview 1811*0Sstevel@tonic-gate * 1812*0Sstevel@tonic-gate * Returns the probe argument associated with the specified probe. 1813*0Sstevel@tonic-gate * 1814*0Sstevel@tonic-gate * 2.9.2 Arguments and Notes 1815*0Sstevel@tonic-gate * 1816*0Sstevel@tonic-gate * The first argument is the provider identifier, as returned from a 1817*0Sstevel@tonic-gate * successful call to dtrace_register(). The second argument is a probe 1818*0Sstevel@tonic-gate * identifier, as returned from dtrace_probe_lookup() or 1819*0Sstevel@tonic-gate * dtrace_probe_create(). This is useful if a probe has multiple 1820*0Sstevel@tonic-gate * provider-specific components to it: the provider can create the probe 1821*0Sstevel@tonic-gate * once with provider-specific state, and then add to the state by looking 1822*0Sstevel@tonic-gate * up the probe based on probe identifier. 1823*0Sstevel@tonic-gate * 1824*0Sstevel@tonic-gate * 2.9.3 Return value 1825*0Sstevel@tonic-gate * 1826*0Sstevel@tonic-gate * Returns the argument associated with the specified probe. If the 1827*0Sstevel@tonic-gate * specified probe does not exist, or if the specified probe is not provided 1828*0Sstevel@tonic-gate * by the specified provider, NULL is returned. 1829*0Sstevel@tonic-gate * 1830*0Sstevel@tonic-gate * 2.9.4 Caller's context 1831*0Sstevel@tonic-gate * 1832*0Sstevel@tonic-gate * While dtrace_probe_arg() is generally expected to be called from 1833*0Sstevel@tonic-gate * dtps_provide() and/or dtps_provide_module(), it may also be called from 1834*0Sstevel@tonic-gate * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1835*0Sstevel@tonic-gate * 1836*0Sstevel@tonic-gate * 2.10 void dtrace_probe(dtrace_id_t probe, uintptr_t arg0, uintptr_t arg1, 1837*0Sstevel@tonic-gate * uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) 1838*0Sstevel@tonic-gate * 1839*0Sstevel@tonic-gate * 2.10.1 Overview 1840*0Sstevel@tonic-gate * 1841*0Sstevel@tonic-gate * The epicenter of DTrace: fires the specified probes with the specified 1842*0Sstevel@tonic-gate * arguments. 1843*0Sstevel@tonic-gate * 1844*0Sstevel@tonic-gate * 2.10.2 Arguments and Notes 1845*0Sstevel@tonic-gate * 1846*0Sstevel@tonic-gate * The first argument is a probe identifier as returned by 1847*0Sstevel@tonic-gate * dtrace_probe_create() or dtrace_probe_lookup(). The second through sixth 1848*0Sstevel@tonic-gate * arguments are the values to which the D variables "arg0" through "arg4" 1849*0Sstevel@tonic-gate * will be mapped. 1850*0Sstevel@tonic-gate * 1851*0Sstevel@tonic-gate * dtrace_probe() should be called whenever the specified probe has fired -- 1852*0Sstevel@tonic-gate * however the provider defines it. 1853*0Sstevel@tonic-gate * 1854*0Sstevel@tonic-gate * 2.10.3 Return value 1855*0Sstevel@tonic-gate * 1856*0Sstevel@tonic-gate * None. 1857*0Sstevel@tonic-gate * 1858*0Sstevel@tonic-gate * 2.10.4 Caller's context 1859*0Sstevel@tonic-gate * 1860*0Sstevel@tonic-gate * dtrace_probe() may be called in virtually any context: kernel, user, 1861*0Sstevel@tonic-gate * interrupt, high-level interrupt, with arbitrary adaptive locks held, with 1862*0Sstevel@tonic-gate * dispatcher locks held, with interrupts disabled, etc. The only latitude 1863*0Sstevel@tonic-gate * that must be afforded to DTrace is the ability to make calls within 1864*0Sstevel@tonic-gate * itself (and to its in-kernel subroutines) and the ability to access 1865*0Sstevel@tonic-gate * arbitrary (but mapped) memory. On some platforms, this constrains 1866*0Sstevel@tonic-gate * context. For example, on UltraSPARC, dtrace_probe() cannot be called 1867*0Sstevel@tonic-gate * from any context in which TL is greater than zero. dtrace_probe() may 1868*0Sstevel@tonic-gate * also not be called from any routine which may be called by dtrace_probe() 1869*0Sstevel@tonic-gate * -- which includes functions in the DTrace framework and some in-kernel 1870*0Sstevel@tonic-gate * DTrace subroutines. All such functions "dtrace_"; providers that 1871*0Sstevel@tonic-gate * instrument the kernel arbitrarily should be sure to not instrument these 1872*0Sstevel@tonic-gate * routines. 1873*0Sstevel@tonic-gate */ 1874*0Sstevel@tonic-gate typedef struct dtrace_pops { 1875*0Sstevel@tonic-gate void (*dtps_provide)(void *arg, const dtrace_probedesc_t *spec); 1876*0Sstevel@tonic-gate void (*dtps_provide_module)(void *arg, struct modctl *mp); 1877*0Sstevel@tonic-gate void (*dtps_enable)(void *arg, dtrace_id_t id, void *parg); 1878*0Sstevel@tonic-gate void (*dtps_disable)(void *arg, dtrace_id_t id, void *parg); 1879*0Sstevel@tonic-gate void (*dtps_suspend)(void *arg, dtrace_id_t id, void *parg); 1880*0Sstevel@tonic-gate void (*dtps_resume)(void *arg, dtrace_id_t id, void *parg); 1881*0Sstevel@tonic-gate void (*dtps_getargdesc)(void *arg, dtrace_id_t id, void *parg, 1882*0Sstevel@tonic-gate dtrace_argdesc_t *desc); 1883*0Sstevel@tonic-gate uint64_t (*dtps_getargval)(void *arg, dtrace_id_t id, void *parg, 1884*0Sstevel@tonic-gate int argno, int aframes); 1885*0Sstevel@tonic-gate int (*dtps_usermode)(void *arg, dtrace_id_t id, void *parg); 1886*0Sstevel@tonic-gate void (*dtps_destroy)(void *arg, dtrace_id_t id, void *parg); 1887*0Sstevel@tonic-gate } dtrace_pops_t; 1888*0Sstevel@tonic-gate 1889*0Sstevel@tonic-gate typedef uintptr_t dtrace_provider_id_t; 1890*0Sstevel@tonic-gate 1891*0Sstevel@tonic-gate extern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, 1892*0Sstevel@tonic-gate uid_t, const dtrace_pops_t *, void *, dtrace_provider_id_t *); 1893*0Sstevel@tonic-gate extern int dtrace_unregister(dtrace_provider_id_t); 1894*0Sstevel@tonic-gate extern int dtrace_condense(dtrace_provider_id_t); 1895*0Sstevel@tonic-gate extern void dtrace_invalidate(dtrace_provider_id_t); 1896*0Sstevel@tonic-gate extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, const char *, 1897*0Sstevel@tonic-gate const char *, const char *); 1898*0Sstevel@tonic-gate extern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *, 1899*0Sstevel@tonic-gate const char *, const char *, int, void *); 1900*0Sstevel@tonic-gate extern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t); 1901*0Sstevel@tonic-gate extern void dtrace_probe(dtrace_id_t, uintptr_t arg0, uintptr_t arg1, 1902*0Sstevel@tonic-gate uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); 1903*0Sstevel@tonic-gate 1904*0Sstevel@tonic-gate /* 1905*0Sstevel@tonic-gate * DTrace Meta Provider API 1906*0Sstevel@tonic-gate * 1907*0Sstevel@tonic-gate * The following functions are implemented by the DTrace framework and are 1908*0Sstevel@tonic-gate * used to implement meta providers. Meta providers plug into the DTrace 1909*0Sstevel@tonic-gate * framework and are used to instantiate new providers on the fly. At 1910*0Sstevel@tonic-gate * present, there is only one type of meta provider and only one meta 1911*0Sstevel@tonic-gate * provider may be registered with the DTrace framework at a time. The 1912*0Sstevel@tonic-gate * sole meta provider type provides user-land static tracing facilities 1913*0Sstevel@tonic-gate * by taking meta probe descriptions and adding a corresponding provider 1914*0Sstevel@tonic-gate * into the DTrace framework. 1915*0Sstevel@tonic-gate * 1916*0Sstevel@tonic-gate * 1 Framework-to-Provider 1917*0Sstevel@tonic-gate * 1918*0Sstevel@tonic-gate * 1.1 Overview 1919*0Sstevel@tonic-gate * 1920*0Sstevel@tonic-gate * The Framework-to-Provider API is represented by the dtrace_mops structure 1921*0Sstevel@tonic-gate * that the meta provider passes to the framework when registering itself as 1922*0Sstevel@tonic-gate * a meta provider. This structure consists of the following members: 1923*0Sstevel@tonic-gate * 1924*0Sstevel@tonic-gate * dtms_create_probe() <-- Add a new probe to a created provider 1925*0Sstevel@tonic-gate * dtms_provide_pid() <-- Create a new provider for a given process 1926*0Sstevel@tonic-gate * dtms_remove_pid() <-- Remove a previously created provider 1927*0Sstevel@tonic-gate * 1928*0Sstevel@tonic-gate * 1.2 void dtms_create_probe(void *arg, void *parg, 1929*0Sstevel@tonic-gate * dtrace_helper_probedesc_t *probedesc); 1930*0Sstevel@tonic-gate * 1931*0Sstevel@tonic-gate * 1.2.1 Overview 1932*0Sstevel@tonic-gate * 1933*0Sstevel@tonic-gate * Called by the DTrace framework to create a new probe in a provider 1934*0Sstevel@tonic-gate * created by this meta provider. 1935*0Sstevel@tonic-gate * 1936*0Sstevel@tonic-gate * 1.2.2 Arguments and notes 1937*0Sstevel@tonic-gate * 1938*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_meta_register(). 1939*0Sstevel@tonic-gate * The second argument is the provider cookie for the associated provider; 1940*0Sstevel@tonic-gate * this is obtained from the return value of dtms_provide_pid(). The third 1941*0Sstevel@tonic-gate * argument is the helper probe description. 1942*0Sstevel@tonic-gate * 1943*0Sstevel@tonic-gate * 1.2.3 Return value 1944*0Sstevel@tonic-gate * 1945*0Sstevel@tonic-gate * None 1946*0Sstevel@tonic-gate * 1947*0Sstevel@tonic-gate * 1.2.4 Caller's context 1948*0Sstevel@tonic-gate * 1949*0Sstevel@tonic-gate * dtms_create_probe() is called from either ioctl() or module load context. 1950*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that meta providers may not 1951*0Sstevel@tonic-gate * register or unregister. This means that the meta provider cannot call 1952*0Sstevel@tonic-gate * dtrace_meta_register() or dtrace_meta_unregister(). However, the context is 1953*0Sstevel@tonic-gate * such that the provider may (and is expected to) call provider-related 1954*0Sstevel@tonic-gate * DTrace provider APIs including dtrace_probe_create(). 1955*0Sstevel@tonic-gate * 1956*0Sstevel@tonic-gate * 1.3 void *dtms_provide_pid(void *arg, dtrace_meta_provider_t *mprov, 1957*0Sstevel@tonic-gate * pid_t pid) 1958*0Sstevel@tonic-gate * 1959*0Sstevel@tonic-gate * 1.3.1 Overview 1960*0Sstevel@tonic-gate * 1961*0Sstevel@tonic-gate * Called by the DTrace framework to instantiate a new provider given the 1962*0Sstevel@tonic-gate * description of the provider and probes in the mprov argument. The 1963*0Sstevel@tonic-gate * meta provider should call dtrace_register() to insert the new provider 1964*0Sstevel@tonic-gate * into the DTrace framework. 1965*0Sstevel@tonic-gate * 1966*0Sstevel@tonic-gate * 1.3.2 Arguments and notes 1967*0Sstevel@tonic-gate * 1968*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_meta_register(). 1969*0Sstevel@tonic-gate * The second argument is a pointer to a structure describing the new 1970*0Sstevel@tonic-gate * helper provider. The third argument is the process identifier for 1971*0Sstevel@tonic-gate * process associated with this new provider. Note that the name of the 1972*0Sstevel@tonic-gate * provider as passed to dtrace_register() should be the contatenation of 1973*0Sstevel@tonic-gate * the dtmpb_provname member of the mprov argument and the processs 1974*0Sstevel@tonic-gate * identifier as a string. 1975*0Sstevel@tonic-gate * 1976*0Sstevel@tonic-gate * 1.3.3 Return value 1977*0Sstevel@tonic-gate * 1978*0Sstevel@tonic-gate * The cookie for the provider that the meta provider creates. This is 1979*0Sstevel@tonic-gate * the same value that it passed to dtrace_register(). 1980*0Sstevel@tonic-gate * 1981*0Sstevel@tonic-gate * 1.3.4 Caller's context 1982*0Sstevel@tonic-gate * 1983*0Sstevel@tonic-gate * dtms_provide_pid() is called from either ioctl() or module load context. 1984*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that meta providers may not 1985*0Sstevel@tonic-gate * register or unregister. This means that the meta provider cannot call 1986*0Sstevel@tonic-gate * dtrace_meta_register() or dtrace_meta_unregister(). However, the context 1987*0Sstevel@tonic-gate * is such that the provider may -- and is expected to -- call 1988*0Sstevel@tonic-gate * provider-related DTrace provider APIs including dtrace_register(). 1989*0Sstevel@tonic-gate * 1990*0Sstevel@tonic-gate * 1.4 void dtms_remove_pid(void *arg, dtrace_meta_provider_t *mprov, 1991*0Sstevel@tonic-gate * pid_t pid) 1992*0Sstevel@tonic-gate * 1993*0Sstevel@tonic-gate * 1.4.1 Overview 1994*0Sstevel@tonic-gate * 1995*0Sstevel@tonic-gate * Called by the DTrace framework to remove a provider that had previously 1996*0Sstevel@tonic-gate * been instantiated via the dtms_provide_pid() entry point. The meta 1997*0Sstevel@tonic-gate * provider need not remove the provider immediately, but this entry 1998*0Sstevel@tonic-gate * point indicates that the provider should be removed as soon as possible 1999*0Sstevel@tonic-gate * using the dtrace_unregister() API. 2000*0Sstevel@tonic-gate * 2001*0Sstevel@tonic-gate * 1.4.2 Arguments and notes 2002*0Sstevel@tonic-gate * 2003*0Sstevel@tonic-gate * The first argument is the cookie as passed to dtrace_meta_register(). 2004*0Sstevel@tonic-gate * The second argument is a pointer to a structure describing the helper 2005*0Sstevel@tonic-gate * provider. The third argument is the process identifier for process 2006*0Sstevel@tonic-gate * associated with this new provider. 2007*0Sstevel@tonic-gate * 2008*0Sstevel@tonic-gate * 1.4.3 Return value 2009*0Sstevel@tonic-gate * 2010*0Sstevel@tonic-gate * None 2011*0Sstevel@tonic-gate * 2012*0Sstevel@tonic-gate * 1.4.4 Caller's context 2013*0Sstevel@tonic-gate * 2014*0Sstevel@tonic-gate * dtms_remove_pid() is called from either ioctl() or exit() context. 2015*0Sstevel@tonic-gate * The DTrace framework is locked in such a way that meta providers may not 2016*0Sstevel@tonic-gate * register or unregister. This means that the meta provider cannot call 2017*0Sstevel@tonic-gate * dtrace_meta_register() or dtrace_meta_unregister(). However, the context 2018*0Sstevel@tonic-gate * is such that the provider may -- and is expected to -- call 2019*0Sstevel@tonic-gate * provider-related DTrace provider APIs including dtrace_unregister(). 2020*0Sstevel@tonic-gate */ 2021*0Sstevel@tonic-gate typedef struct dtrace_helper_probedesc { 2022*0Sstevel@tonic-gate char *dthpb_mod; /* probe module */ 2023*0Sstevel@tonic-gate char *dthpb_func; /* probe function */ 2024*0Sstevel@tonic-gate char *dthpb_name; /* probe name */ 2025*0Sstevel@tonic-gate uint64_t dthpb_base; /* base address */ 2026*0Sstevel@tonic-gate uint32_t *dthpb_offs; /* offsets array */ 2027*0Sstevel@tonic-gate uint32_t dthpb_noffs; /* offsets count */ 2028*0Sstevel@tonic-gate uint8_t *dthpb_args; /* argument mapping array */ 2029*0Sstevel@tonic-gate uint8_t dthpb_xargc; /* translated argument count */ 2030*0Sstevel@tonic-gate uint8_t dthpb_nargc; /* native argument count */ 2031*0Sstevel@tonic-gate char *dthpb_xtypes; /* translated types strings */ 2032*0Sstevel@tonic-gate char *dthpb_ntypes; /* native types strings */ 2033*0Sstevel@tonic-gate } dtrace_helper_probedesc_t; 2034*0Sstevel@tonic-gate 2035*0Sstevel@tonic-gate typedef struct dtrace_helper_provdesc { 2036*0Sstevel@tonic-gate char *dthpv_provname; /* provider name */ 2037*0Sstevel@tonic-gate dtrace_pattr_t dthpv_pattr; /* stability attributes */ 2038*0Sstevel@tonic-gate } dtrace_helper_provdesc_t; 2039*0Sstevel@tonic-gate 2040*0Sstevel@tonic-gate typedef struct dtrace_mops { 2041*0Sstevel@tonic-gate void (*dtms_create_probe)(void *, void *, dtrace_helper_probedesc_t *); 2042*0Sstevel@tonic-gate void *(*dtms_provide_pid)(void *, dtrace_helper_provdesc_t *, pid_t); 2043*0Sstevel@tonic-gate void (*dtms_remove_pid)(void *, dtrace_helper_provdesc_t *, pid_t); 2044*0Sstevel@tonic-gate } dtrace_mops_t; 2045*0Sstevel@tonic-gate 2046*0Sstevel@tonic-gate typedef uintptr_t dtrace_meta_provider_id_t; 2047*0Sstevel@tonic-gate 2048*0Sstevel@tonic-gate extern int dtrace_meta_register(const char *, const dtrace_mops_t *, void *, 2049*0Sstevel@tonic-gate dtrace_meta_provider_id_t *); 2050*0Sstevel@tonic-gate extern int dtrace_meta_unregister(dtrace_meta_provider_id_t); 2051*0Sstevel@tonic-gate 2052*0Sstevel@tonic-gate /* 2053*0Sstevel@tonic-gate * DTrace Kernel Hooks 2054*0Sstevel@tonic-gate * 2055*0Sstevel@tonic-gate * The following functions are implemented by the base kernel and form a set of 2056*0Sstevel@tonic-gate * hooks used by the DTrace framework. DTrace hooks are implemented in either 2057*0Sstevel@tonic-gate * uts/common/os/dtrace_subr.c, an ISA-specific assembly file, or in a 2058*0Sstevel@tonic-gate * uts/<platform>/os/dtrace_subr.c corresponding to each hardware platform. 2059*0Sstevel@tonic-gate */ 2060*0Sstevel@tonic-gate 2061*0Sstevel@tonic-gate typedef enum dtrace_vtime_state { 2062*0Sstevel@tonic-gate DTRACE_VTIME_INACTIVE = 0, /* No DTrace, no TNF */ 2063*0Sstevel@tonic-gate DTRACE_VTIME_ACTIVE, /* DTrace virtual time, no TNF */ 2064*0Sstevel@tonic-gate DTRACE_VTIME_INACTIVE_TNF, /* No DTrace, TNF active */ 2065*0Sstevel@tonic-gate DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ 2066*0Sstevel@tonic-gate } dtrace_vtime_state_t; 2067*0Sstevel@tonic-gate 2068*0Sstevel@tonic-gate extern dtrace_vtime_state_t dtrace_vtime_active; 2069*0Sstevel@tonic-gate extern void dtrace_vtime_switch(kthread_t *next); 2070*0Sstevel@tonic-gate extern void dtrace_vtime_enable_tnf(void); 2071*0Sstevel@tonic-gate extern void dtrace_vtime_disable_tnf(void); 2072*0Sstevel@tonic-gate extern void dtrace_vtime_enable(void); 2073*0Sstevel@tonic-gate extern void dtrace_vtime_disable(void); 2074*0Sstevel@tonic-gate 2075*0Sstevel@tonic-gate struct regs; 2076*0Sstevel@tonic-gate 2077*0Sstevel@tonic-gate extern int (*dtrace_pid_probe_ptr)(struct regs *); 2078*0Sstevel@tonic-gate extern int (*dtrace_fasttrap_probe_ptr)(struct regs *); 2079*0Sstevel@tonic-gate extern int (*dtrace_return_probe_ptr)(struct regs *); 2080*0Sstevel@tonic-gate extern void (*dtrace_fasttrap_fork_ptr)(proc_t *, proc_t *); 2081*0Sstevel@tonic-gate extern void (*dtrace_fasttrap_exec_ptr)(proc_t *); 2082*0Sstevel@tonic-gate extern void (*dtrace_fasttrap_exit_ptr)(proc_t *); 2083*0Sstevel@tonic-gate extern void dtrace_fasttrap_fork(proc_t *, proc_t *); 2084*0Sstevel@tonic-gate 2085*0Sstevel@tonic-gate typedef uintptr_t dtrace_icookie_t; 2086*0Sstevel@tonic-gate typedef void (*dtrace_xcall_t)(void *); 2087*0Sstevel@tonic-gate 2088*0Sstevel@tonic-gate extern dtrace_icookie_t dtrace_interrupt_disable(void); 2089*0Sstevel@tonic-gate extern void dtrace_interrupt_enable(dtrace_icookie_t); 2090*0Sstevel@tonic-gate 2091*0Sstevel@tonic-gate extern void dtrace_membar_producer(void); 2092*0Sstevel@tonic-gate extern void dtrace_membar_consumer(void); 2093*0Sstevel@tonic-gate 2094*0Sstevel@tonic-gate extern void (*dtrace_cpu_init)(processorid_t); 2095*0Sstevel@tonic-gate extern void (*dtrace_modload)(struct modctl *); 2096*0Sstevel@tonic-gate extern void (*dtrace_modunload)(struct modctl *); 2097*0Sstevel@tonic-gate extern void (*dtrace_helpers_cleanup)(); 2098*0Sstevel@tonic-gate extern void (*dtrace_helpers_fork)(proc_t *parent, proc_t *child); 2099*0Sstevel@tonic-gate extern void (*dtrace_cpustart_init)(); 2100*0Sstevel@tonic-gate extern void (*dtrace_cpustart_fini)(); 2101*0Sstevel@tonic-gate 2102*0Sstevel@tonic-gate extern void (*dtrace_kreloc_init)(); 2103*0Sstevel@tonic-gate extern void (*dtrace_kreloc_fini)(); 2104*0Sstevel@tonic-gate 2105*0Sstevel@tonic-gate extern void (*dtrace_debugger_init)(); 2106*0Sstevel@tonic-gate extern void (*dtrace_debugger_fini)(); 2107*0Sstevel@tonic-gate extern dtrace_cacheid_t dtrace_predcache_id; 2108*0Sstevel@tonic-gate 2109*0Sstevel@tonic-gate extern hrtime_t dtrace_gethrtime(void); 2110*0Sstevel@tonic-gate extern void dtrace_sync(void); 2111*0Sstevel@tonic-gate extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); 2112*0Sstevel@tonic-gate extern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *); 2113*0Sstevel@tonic-gate extern void dtrace_vpanic(const char *, __va_list); 2114*0Sstevel@tonic-gate extern void dtrace_panic(const char *, ...); 2115*0Sstevel@tonic-gate 2116*0Sstevel@tonic-gate extern int dtrace_safe_defer_signal(void); 2117*0Sstevel@tonic-gate extern void dtrace_safe_synchronous_signal(void); 2118*0Sstevel@tonic-gate 2119*0Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 2120*0Sstevel@tonic-gate extern int dtrace_instr_size(uchar_t *instr); 2121*0Sstevel@tonic-gate extern int dtrace_instr_size_isa(uchar_t *, model_t, int *); 2122*0Sstevel@tonic-gate extern void dtrace_invop_add(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 2123*0Sstevel@tonic-gate extern void dtrace_invop_remove(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 2124*0Sstevel@tonic-gate extern void dtrace_invop_callsite(void); 2125*0Sstevel@tonic-gate #endif 2126*0Sstevel@tonic-gate 2127*0Sstevel@tonic-gate #ifdef __sparc 2128*0Sstevel@tonic-gate extern int dtrace_blksuword32(uintptr_t, uint32_t *, int); 2129*0Sstevel@tonic-gate extern void dtrace_getfsr(uint64_t *); 2130*0Sstevel@tonic-gate #endif 2131*0Sstevel@tonic-gate 2132*0Sstevel@tonic-gate #define DTRACE_CPUFLAG_ISSET(flag) \ 2133*0Sstevel@tonic-gate (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & (flag)) 2134*0Sstevel@tonic-gate 2135*0Sstevel@tonic-gate #define DTRACE_CPUFLAG_SET(flag) \ 2136*0Sstevel@tonic-gate (cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= (flag)) 2137*0Sstevel@tonic-gate 2138*0Sstevel@tonic-gate #define DTRACE_CPUFLAG_CLEAR(flag) \ 2139*0Sstevel@tonic-gate (cpu_core[CPU->cpu_id].cpuc_dtrace_flags &= ~(flag)) 2140*0Sstevel@tonic-gate 2141*0Sstevel@tonic-gate #endif /* _KERNEL */ 2142*0Sstevel@tonic-gate 2143*0Sstevel@tonic-gate #endif /* _ASM */ 2144*0Sstevel@tonic-gate 2145*0Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 2146*0Sstevel@tonic-gate 2147*0Sstevel@tonic-gate #define DTRACE_INVOP_PUSHL_EBP 1 2148*0Sstevel@tonic-gate #define DTRACE_INVOP_POPL_EBP 2 2149*0Sstevel@tonic-gate #define DTRACE_INVOP_LEAVE 3 2150*0Sstevel@tonic-gate #define DTRACE_INVOP_NOP 4 2151*0Sstevel@tonic-gate #define DTRACE_INVOP_RET 5 2152*0Sstevel@tonic-gate 2153*0Sstevel@tonic-gate #endif 2154*0Sstevel@tonic-gate 2155*0Sstevel@tonic-gate #ifdef __cplusplus 2156*0Sstevel@tonic-gate } 2157*0Sstevel@tonic-gate #endif 2158*0Sstevel@tonic-gate 2159*0Sstevel@tonic-gate #endif /* _SYS_DTRACE_H */ 2160