dtrace.h revision 179193
1179193Sjb/* 2179193Sjb * CDDL HEADER START 3179193Sjb * 4179193Sjb * The contents of this file are subject to the terms of the 5179193Sjb * Common Development and Distribution License (the "License"). 6179193Sjb * You may not use this file except in compliance with the License. 7179193Sjb * 8179193Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9179193Sjb * or http://www.opensolaris.org/os/licensing. 10179193Sjb * See the License for the specific language governing permissions 11179193Sjb * and limitations under the License. 12179193Sjb * 13179193Sjb * When distributing Covered Code, include this CDDL HEADER in each 14179193Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15179193Sjb * If applicable, add the following below this CDDL HEADER, with the 16179193Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17179193Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18179193Sjb * 19179193Sjb * CDDL HEADER END 20179193Sjb */ 21179193Sjb 22179193Sjb/* 23179193Sjb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24179193Sjb * Use is subject to license terms. 25179193Sjb */ 26179193Sjb 27179193Sjb#ifndef _SYS_DTRACE_H 28179193Sjb#define _SYS_DTRACE_H 29179193Sjb 30179193Sjb#pragma ident "%Z%%M% %I% %E% SMI" 31179193Sjb 32179193Sjb#ifdef __cplusplus 33179193Sjbextern "C" { 34179193Sjb#endif 35179193Sjb 36179193Sjb/* 37179193Sjb * DTrace Dynamic Tracing Software: Kernel Interfaces 38179193Sjb * 39179193Sjb * Note: The contents of this file are private to the implementation of the 40179193Sjb * Solaris system and DTrace subsystem and are subject to change at any time 41179193Sjb * without notice. Applications and drivers using these interfaces will fail 42179193Sjb * to run on future releases. These interfaces should not be used for any 43179193Sjb * purpose except those expressly outlined in dtrace(7D) and libdtrace(3LIB). 44179193Sjb * Please refer to the "Solaris Dynamic Tracing Guide" for more information. 45179193Sjb */ 46179193Sjb 47179193Sjb#ifndef _ASM 48179193Sjb 49179193Sjb#include <sys/types.h> 50179193Sjb#include <sys/modctl.h> 51179193Sjb#include <sys/processor.h> 52179193Sjb#include <sys/systm.h> 53179193Sjb#include <sys/ctf_api.h> 54179193Sjb#include <sys/cyclic.h> 55179193Sjb#include <sys/int_limits.h> 56179193Sjb 57179193Sjb/* 58179193Sjb * DTrace Universal Constants and Typedefs 59179193Sjb */ 60179193Sjb#define DTRACE_CPUALL -1 /* all CPUs */ 61179193Sjb#define DTRACE_IDNONE 0 /* invalid probe identifier */ 62179193Sjb#define DTRACE_EPIDNONE 0 /* invalid enabled probe identifier */ 63179193Sjb#define DTRACE_AGGIDNONE 0 /* invalid aggregation identifier */ 64179193Sjb#define DTRACE_AGGVARIDNONE 0 /* invalid aggregation variable ID */ 65179193Sjb#define DTRACE_CACHEIDNONE 0 /* invalid predicate cache */ 66179193Sjb#define DTRACE_PROVNONE 0 /* invalid provider identifier */ 67179193Sjb#define DTRACE_METAPROVNONE 0 /* invalid meta-provider identifier */ 68179193Sjb#define DTRACE_ARGNONE -1 /* invalid argument index */ 69179193Sjb 70179193Sjb#define DTRACE_PROVNAMELEN 64 71179193Sjb#define DTRACE_MODNAMELEN 64 72179193Sjb#define DTRACE_FUNCNAMELEN 128 73179193Sjb#define DTRACE_NAMELEN 64 74179193Sjb#define DTRACE_FULLNAMELEN (DTRACE_PROVNAMELEN + DTRACE_MODNAMELEN + \ 75179193Sjb DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 4) 76179193Sjb#define DTRACE_ARGTYPELEN 128 77179193Sjb 78179193Sjbtypedef uint32_t dtrace_id_t; /* probe identifier */ 79179193Sjbtypedef uint32_t dtrace_epid_t; /* enabled probe identifier */ 80179193Sjbtypedef uint32_t dtrace_aggid_t; /* aggregation identifier */ 81179193Sjbtypedef int64_t dtrace_aggvarid_t; /* aggregation variable identifier */ 82179193Sjbtypedef uint16_t dtrace_actkind_t; /* action kind */ 83179193Sjbtypedef int64_t dtrace_optval_t; /* option value */ 84179193Sjbtypedef uint32_t dtrace_cacheid_t; /* predicate cache identifier */ 85179193Sjb 86179193Sjbtypedef enum dtrace_probespec { 87179193Sjb DTRACE_PROBESPEC_NONE = -1, 88179193Sjb DTRACE_PROBESPEC_PROVIDER = 0, 89179193Sjb DTRACE_PROBESPEC_MOD, 90179193Sjb DTRACE_PROBESPEC_FUNC, 91179193Sjb DTRACE_PROBESPEC_NAME 92179193Sjb} dtrace_probespec_t; 93179193Sjb 94179193Sjb/* 95179193Sjb * DTrace Intermediate Format (DIF) 96179193Sjb * 97179193Sjb * The following definitions describe the DTrace Intermediate Format (DIF), a 98179193Sjb * a RISC-like instruction set and program encoding used to represent 99179193Sjb * predicates and actions that can be bound to DTrace probes. The constants 100179193Sjb * below defining the number of available registers are suggested minimums; the 101179193Sjb * compiler should use DTRACEIOC_CONF to dynamically obtain the number of 102179193Sjb * registers provided by the current DTrace implementation. 103179193Sjb */ 104179193Sjb#define DIF_VERSION_1 1 /* DIF version 1: Solaris 10 Beta */ 105179193Sjb#define DIF_VERSION_2 2 /* DIF version 2: Solaris 10 FCS */ 106179193Sjb#define DIF_VERSION DIF_VERSION_2 /* latest DIF instruction set version */ 107179193Sjb#define DIF_DIR_NREGS 8 /* number of DIF integer registers */ 108179193Sjb#define DIF_DTR_NREGS 8 /* number of DIF tuple registers */ 109179193Sjb 110179193Sjb#define DIF_OP_OR 1 /* or r1, r2, rd */ 111179193Sjb#define DIF_OP_XOR 2 /* xor r1, r2, rd */ 112179193Sjb#define DIF_OP_AND 3 /* and r1, r2, rd */ 113179193Sjb#define DIF_OP_SLL 4 /* sll r1, r2, rd */ 114179193Sjb#define DIF_OP_SRL 5 /* srl r1, r2, rd */ 115179193Sjb#define DIF_OP_SUB 6 /* sub r1, r2, rd */ 116179193Sjb#define DIF_OP_ADD 7 /* add r1, r2, rd */ 117179193Sjb#define DIF_OP_MUL 8 /* mul r1, r2, rd */ 118179193Sjb#define DIF_OP_SDIV 9 /* sdiv r1, r2, rd */ 119179193Sjb#define DIF_OP_UDIV 10 /* udiv r1, r2, rd */ 120179193Sjb#define DIF_OP_SREM 11 /* srem r1, r2, rd */ 121179193Sjb#define DIF_OP_UREM 12 /* urem r1, r2, rd */ 122179193Sjb#define DIF_OP_NOT 13 /* not r1, rd */ 123179193Sjb#define DIF_OP_MOV 14 /* mov r1, rd */ 124179193Sjb#define DIF_OP_CMP 15 /* cmp r1, r2 */ 125179193Sjb#define DIF_OP_TST 16 /* tst r1 */ 126179193Sjb#define DIF_OP_BA 17 /* ba label */ 127179193Sjb#define DIF_OP_BE 18 /* be label */ 128179193Sjb#define DIF_OP_BNE 19 /* bne label */ 129179193Sjb#define DIF_OP_BG 20 /* bg label */ 130179193Sjb#define DIF_OP_BGU 21 /* bgu label */ 131179193Sjb#define DIF_OP_BGE 22 /* bge label */ 132179193Sjb#define DIF_OP_BGEU 23 /* bgeu label */ 133179193Sjb#define DIF_OP_BL 24 /* bl label */ 134179193Sjb#define DIF_OP_BLU 25 /* blu label */ 135179193Sjb#define DIF_OP_BLE 26 /* ble label */ 136179193Sjb#define DIF_OP_BLEU 27 /* bleu label */ 137179193Sjb#define DIF_OP_LDSB 28 /* ldsb [r1], rd */ 138179193Sjb#define DIF_OP_LDSH 29 /* ldsh [r1], rd */ 139179193Sjb#define DIF_OP_LDSW 30 /* ldsw [r1], rd */ 140179193Sjb#define DIF_OP_LDUB 31 /* ldub [r1], rd */ 141179193Sjb#define DIF_OP_LDUH 32 /* lduh [r1], rd */ 142179193Sjb#define DIF_OP_LDUW 33 /* lduw [r1], rd */ 143179193Sjb#define DIF_OP_LDX 34 /* ldx [r1], rd */ 144179193Sjb#define DIF_OP_RET 35 /* ret rd */ 145179193Sjb#define DIF_OP_NOP 36 /* nop */ 146179193Sjb#define DIF_OP_SETX 37 /* setx intindex, rd */ 147179193Sjb#define DIF_OP_SETS 38 /* sets strindex, rd */ 148179193Sjb#define DIF_OP_SCMP 39 /* scmp r1, r2 */ 149179193Sjb#define DIF_OP_LDGA 40 /* ldga var, ri, rd */ 150179193Sjb#define DIF_OP_LDGS 41 /* ldgs var, rd */ 151179193Sjb#define DIF_OP_STGS 42 /* stgs var, rs */ 152179193Sjb#define DIF_OP_LDTA 43 /* ldta var, ri, rd */ 153179193Sjb#define DIF_OP_LDTS 44 /* ldts var, rd */ 154179193Sjb#define DIF_OP_STTS 45 /* stts var, rs */ 155179193Sjb#define DIF_OP_SRA 46 /* sra r1, r2, rd */ 156179193Sjb#define DIF_OP_CALL 47 /* call subr, rd */ 157179193Sjb#define DIF_OP_PUSHTR 48 /* pushtr type, rs, rr */ 158179193Sjb#define DIF_OP_PUSHTV 49 /* pushtv type, rs, rv */ 159179193Sjb#define DIF_OP_POPTS 50 /* popts */ 160179193Sjb#define DIF_OP_FLUSHTS 51 /* flushts */ 161179193Sjb#define DIF_OP_LDGAA 52 /* ldgaa var, rd */ 162179193Sjb#define DIF_OP_LDTAA 53 /* ldtaa var, rd */ 163179193Sjb#define DIF_OP_STGAA 54 /* stgaa var, rs */ 164179193Sjb#define DIF_OP_STTAA 55 /* sttaa var, rs */ 165179193Sjb#define DIF_OP_LDLS 56 /* ldls var, rd */ 166179193Sjb#define DIF_OP_STLS 57 /* stls var, rs */ 167179193Sjb#define DIF_OP_ALLOCS 58 /* allocs r1, rd */ 168179193Sjb#define DIF_OP_COPYS 59 /* copys r1, r2, rd */ 169179193Sjb#define DIF_OP_STB 60 /* stb r1, [rd] */ 170179193Sjb#define DIF_OP_STH 61 /* sth r1, [rd] */ 171179193Sjb#define DIF_OP_STW 62 /* stw r1, [rd] */ 172179193Sjb#define DIF_OP_STX 63 /* stx r1, [rd] */ 173179193Sjb#define DIF_OP_ULDSB 64 /* uldsb [r1], rd */ 174179193Sjb#define DIF_OP_ULDSH 65 /* uldsh [r1], rd */ 175179193Sjb#define DIF_OP_ULDSW 66 /* uldsw [r1], rd */ 176179193Sjb#define DIF_OP_ULDUB 67 /* uldub [r1], rd */ 177179193Sjb#define DIF_OP_ULDUH 68 /* ulduh [r1], rd */ 178179193Sjb#define DIF_OP_ULDUW 69 /* ulduw [r1], rd */ 179179193Sjb#define DIF_OP_ULDX 70 /* uldx [r1], rd */ 180179193Sjb#define DIF_OP_RLDSB 71 /* rldsb [r1], rd */ 181179193Sjb#define DIF_OP_RLDSH 72 /* rldsh [r1], rd */ 182179193Sjb#define DIF_OP_RLDSW 73 /* rldsw [r1], rd */ 183179193Sjb#define DIF_OP_RLDUB 74 /* rldub [r1], rd */ 184179193Sjb#define DIF_OP_RLDUH 75 /* rlduh [r1], rd */ 185179193Sjb#define DIF_OP_RLDUW 76 /* rlduw [r1], rd */ 186179193Sjb#define DIF_OP_RLDX 77 /* rldx [r1], rd */ 187179193Sjb#define DIF_OP_XLATE 78 /* xlate xlrindex, rd */ 188179193Sjb#define DIF_OP_XLARG 79 /* xlarg xlrindex, rd */ 189179193Sjb 190179193Sjb#define DIF_INTOFF_MAX 0xffff /* highest integer table offset */ 191179193Sjb#define DIF_STROFF_MAX 0xffff /* highest string table offset */ 192179193Sjb#define DIF_REGISTER_MAX 0xff /* highest register number */ 193179193Sjb#define DIF_VARIABLE_MAX 0xffff /* highest variable identifier */ 194179193Sjb#define DIF_SUBROUTINE_MAX 0xffff /* highest subroutine code */ 195179193Sjb 196179193Sjb#define DIF_VAR_ARRAY_MIN 0x0000 /* lowest numbered array variable */ 197179193Sjb#define DIF_VAR_ARRAY_UBASE 0x0080 /* lowest user-defined array */ 198179193Sjb#define DIF_VAR_ARRAY_MAX 0x00ff /* highest numbered array variable */ 199179193Sjb 200179193Sjb#define DIF_VAR_OTHER_MIN 0x0100 /* lowest numbered scalar or assc */ 201179193Sjb#define DIF_VAR_OTHER_UBASE 0x0500 /* lowest user-defined scalar or assc */ 202179193Sjb#define DIF_VAR_OTHER_MAX 0xffff /* highest numbered scalar or assc */ 203179193Sjb 204179193Sjb#define DIF_VAR_ARGS 0x0000 /* arguments array */ 205179193Sjb#define DIF_VAR_REGS 0x0001 /* registers array */ 206179193Sjb#define DIF_VAR_UREGS 0x0002 /* user registers array */ 207179193Sjb#define DIF_VAR_CURTHREAD 0x0100 /* thread pointer */ 208179193Sjb#define DIF_VAR_TIMESTAMP 0x0101 /* timestamp */ 209179193Sjb#define DIF_VAR_VTIMESTAMP 0x0102 /* virtual timestamp */ 210179193Sjb#define DIF_VAR_IPL 0x0103 /* interrupt priority level */ 211179193Sjb#define DIF_VAR_EPID 0x0104 /* enabled probe ID */ 212179193Sjb#define DIF_VAR_ID 0x0105 /* probe ID */ 213179193Sjb#define DIF_VAR_ARG0 0x0106 /* first argument */ 214179193Sjb#define DIF_VAR_ARG1 0x0107 /* second argument */ 215179193Sjb#define DIF_VAR_ARG2 0x0108 /* third argument */ 216179193Sjb#define DIF_VAR_ARG3 0x0109 /* fourth argument */ 217179193Sjb#define DIF_VAR_ARG4 0x010a /* fifth argument */ 218179193Sjb#define DIF_VAR_ARG5 0x010b /* sixth argument */ 219179193Sjb#define DIF_VAR_ARG6 0x010c /* seventh argument */ 220179193Sjb#define DIF_VAR_ARG7 0x010d /* eighth argument */ 221179193Sjb#define DIF_VAR_ARG8 0x010e /* ninth argument */ 222179193Sjb#define DIF_VAR_ARG9 0x010f /* tenth argument */ 223179193Sjb#define DIF_VAR_STACKDEPTH 0x0110 /* stack depth */ 224179193Sjb#define DIF_VAR_CALLER 0x0111 /* caller */ 225179193Sjb#define DIF_VAR_PROBEPROV 0x0112 /* probe provider */ 226179193Sjb#define DIF_VAR_PROBEMOD 0x0113 /* probe module */ 227179193Sjb#define DIF_VAR_PROBEFUNC 0x0114 /* probe function */ 228179193Sjb#define DIF_VAR_PROBENAME 0x0115 /* probe name */ 229179193Sjb#define DIF_VAR_PID 0x0116 /* process ID */ 230179193Sjb#define DIF_VAR_TID 0x0117 /* (per-process) thread ID */ 231179193Sjb#define DIF_VAR_EXECNAME 0x0118 /* name of executable */ 232179193Sjb#define DIF_VAR_ZONENAME 0x0119 /* zone name associated with process */ 233179193Sjb#define DIF_VAR_WALLTIMESTAMP 0x011a /* wall-clock timestamp */ 234179193Sjb#define DIF_VAR_USTACKDEPTH 0x011b /* user-land stack depth */ 235179193Sjb#define DIF_VAR_UCALLER 0x011c /* user-level caller */ 236179193Sjb#define DIF_VAR_PPID 0x011d /* parent process ID */ 237179193Sjb#define DIF_VAR_UID 0x011e /* process user ID */ 238179193Sjb#define DIF_VAR_GID 0x011f /* process group ID */ 239179193Sjb#define DIF_VAR_ERRNO 0x0120 /* thread errno */ 240179193Sjb 241179193Sjb#define DIF_SUBR_RAND 0 242179193Sjb#define DIF_SUBR_MUTEX_OWNED 1 243179193Sjb#define DIF_SUBR_MUTEX_OWNER 2 244179193Sjb#define DIF_SUBR_MUTEX_TYPE_ADAPTIVE 3 245179193Sjb#define DIF_SUBR_MUTEX_TYPE_SPIN 4 246179193Sjb#define DIF_SUBR_RW_READ_HELD 5 247179193Sjb#define DIF_SUBR_RW_WRITE_HELD 6 248179193Sjb#define DIF_SUBR_RW_ISWRITER 7 249179193Sjb#define DIF_SUBR_COPYIN 8 250179193Sjb#define DIF_SUBR_COPYINSTR 9 251179193Sjb#define DIF_SUBR_SPECULATION 10 252179193Sjb#define DIF_SUBR_PROGENYOF 11 253179193Sjb#define DIF_SUBR_STRLEN 12 254179193Sjb#define DIF_SUBR_COPYOUT 13 255179193Sjb#define DIF_SUBR_COPYOUTSTR 14 256179193Sjb#define DIF_SUBR_ALLOCA 15 257179193Sjb#define DIF_SUBR_BCOPY 16 258179193Sjb#define DIF_SUBR_COPYINTO 17 259179193Sjb#define DIF_SUBR_MSGDSIZE 18 260179193Sjb#define DIF_SUBR_MSGSIZE 19 261179193Sjb#define DIF_SUBR_GETMAJOR 20 262179193Sjb#define DIF_SUBR_GETMINOR 21 263179193Sjb#define DIF_SUBR_DDI_PATHNAME 22 264179193Sjb#define DIF_SUBR_STRJOIN 23 265179193Sjb#define DIF_SUBR_LLTOSTR 24 266179193Sjb#define DIF_SUBR_BASENAME 25 267179193Sjb#define DIF_SUBR_DIRNAME 26 268179193Sjb#define DIF_SUBR_CLEANPATH 27 269179193Sjb#define DIF_SUBR_STRCHR 28 270179193Sjb#define DIF_SUBR_STRRCHR 29 271179193Sjb#define DIF_SUBR_STRSTR 30 272179193Sjb#define DIF_SUBR_STRTOK 31 273179193Sjb#define DIF_SUBR_SUBSTR 32 274179193Sjb#define DIF_SUBR_INDEX 33 275179193Sjb#define DIF_SUBR_RINDEX 34 276179193Sjb#define DIF_SUBR_HTONS 35 277179193Sjb#define DIF_SUBR_HTONL 36 278179193Sjb#define DIF_SUBR_HTONLL 37 279179193Sjb#define DIF_SUBR_NTOHS 38 280179193Sjb#define DIF_SUBR_NTOHL 39 281179193Sjb#define DIF_SUBR_NTOHLL 40 282179193Sjb#define DIF_SUBR_INET_NTOP 41 283179193Sjb#define DIF_SUBR_INET_NTOA 42 284179193Sjb#define DIF_SUBR_INET_NTOA6 43 285179193Sjb 286179193Sjb#define DIF_SUBR_MAX 43 /* max subroutine value */ 287179193Sjb 288179193Sjbtypedef uint32_t dif_instr_t; 289179193Sjb 290179193Sjb#define DIF_INSTR_OP(i) (((i) >> 24) & 0xff) 291179193Sjb#define DIF_INSTR_R1(i) (((i) >> 16) & 0xff) 292179193Sjb#define DIF_INSTR_R2(i) (((i) >> 8) & 0xff) 293179193Sjb#define DIF_INSTR_RD(i) ((i) & 0xff) 294179193Sjb#define DIF_INSTR_RS(i) ((i) & 0xff) 295179193Sjb#define DIF_INSTR_LABEL(i) ((i) & 0xffffff) 296179193Sjb#define DIF_INSTR_VAR(i) (((i) >> 8) & 0xffff) 297179193Sjb#define DIF_INSTR_INTEGER(i) (((i) >> 8) & 0xffff) 298179193Sjb#define DIF_INSTR_STRING(i) (((i) >> 8) & 0xffff) 299179193Sjb#define DIF_INSTR_SUBR(i) (((i) >> 8) & 0xffff) 300179193Sjb#define DIF_INSTR_TYPE(i) (((i) >> 16) & 0xff) 301179193Sjb#define DIF_INSTR_XLREF(i) (((i) >> 8) & 0xffff) 302179193Sjb 303179193Sjb#define DIF_INSTR_FMT(op, r1, r2, d) \ 304179193Sjb (((op) << 24) | ((r1) << 16) | ((r2) << 8) | (d)) 305179193Sjb 306179193Sjb#define DIF_INSTR_NOT(r1, d) (DIF_INSTR_FMT(DIF_OP_NOT, r1, 0, d)) 307179193Sjb#define DIF_INSTR_MOV(r1, d) (DIF_INSTR_FMT(DIF_OP_MOV, r1, 0, d)) 308179193Sjb#define DIF_INSTR_CMP(op, r1, r2) (DIF_INSTR_FMT(op, r1, r2, 0)) 309179193Sjb#define DIF_INSTR_TST(r1) (DIF_INSTR_FMT(DIF_OP_TST, r1, 0, 0)) 310179193Sjb#define DIF_INSTR_BRANCH(op, label) (((op) << 24) | (label)) 311179193Sjb#define DIF_INSTR_LOAD(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) 312179193Sjb#define DIF_INSTR_STORE(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) 313179193Sjb#define DIF_INSTR_SETX(i, d) ((DIF_OP_SETX << 24) | ((i) << 8) | (d)) 314179193Sjb#define DIF_INSTR_SETS(s, d) ((DIF_OP_SETS << 24) | ((s) << 8) | (d)) 315179193Sjb#define DIF_INSTR_RET(d) (DIF_INSTR_FMT(DIF_OP_RET, 0, 0, d)) 316179193Sjb#define DIF_INSTR_NOP (DIF_OP_NOP << 24) 317179193Sjb#define DIF_INSTR_LDA(op, v, r, d) (DIF_INSTR_FMT(op, v, r, d)) 318179193Sjb#define DIF_INSTR_LDV(op, v, d) (((op) << 24) | ((v) << 8) | (d)) 319179193Sjb#define DIF_INSTR_STV(op, v, rs) (((op) << 24) | ((v) << 8) | (rs)) 320179193Sjb#define DIF_INSTR_CALL(s, d) ((DIF_OP_CALL << 24) | ((s) << 8) | (d)) 321179193Sjb#define DIF_INSTR_PUSHTS(op, t, r2, rs) (DIF_INSTR_FMT(op, t, r2, rs)) 322179193Sjb#define DIF_INSTR_POPTS (DIF_OP_POPTS << 24) 323179193Sjb#define DIF_INSTR_FLUSHTS (DIF_OP_FLUSHTS << 24) 324179193Sjb#define DIF_INSTR_ALLOCS(r1, d) (DIF_INSTR_FMT(DIF_OP_ALLOCS, r1, 0, d)) 325179193Sjb#define DIF_INSTR_COPYS(r1, r2, d) (DIF_INSTR_FMT(DIF_OP_COPYS, r1, r2, d)) 326179193Sjb#define DIF_INSTR_XLATE(op, r, d) (((op) << 24) | ((r) << 8) | (d)) 327179193Sjb 328179193Sjb#define DIF_REG_R0 0 /* %r0 is always set to zero */ 329179193Sjb 330179193Sjb/* 331179193Sjb * A DTrace Intermediate Format Type (DIF Type) is used to represent the types 332179193Sjb * of variables, function and associative array arguments, and the return type 333179193Sjb * for each DIF object (shown below). It contains a description of the type, 334179193Sjb * its size in bytes, and a module identifier. 335179193Sjb */ 336179193Sjbtypedef struct dtrace_diftype { 337179193Sjb uint8_t dtdt_kind; /* type kind (see below) */ 338179193Sjb uint8_t dtdt_ckind; /* type kind in CTF */ 339179193Sjb uint8_t dtdt_flags; /* type flags (see below) */ 340179193Sjb uint8_t dtdt_pad; /* reserved for future use */ 341179193Sjb uint32_t dtdt_size; /* type size in bytes (unless string) */ 342179193Sjb} dtrace_diftype_t; 343179193Sjb 344179193Sjb#define DIF_TYPE_CTF 0 /* type is a CTF type */ 345179193Sjb#define DIF_TYPE_STRING 1 /* type is a D string */ 346179193Sjb 347179193Sjb#define DIF_TF_BYREF 0x1 /* type is passed by reference */ 348179193Sjb 349179193Sjb/* 350179193Sjb * A DTrace Intermediate Format variable record is used to describe each of the 351179193Sjb * variables referenced by a given DIF object. It contains an integer variable 352179193Sjb * identifier along with variable scope and properties, as shown below. The 353179193Sjb * size of this structure must be sizeof (int) aligned. 354179193Sjb */ 355179193Sjbtypedef struct dtrace_difv { 356179193Sjb uint32_t dtdv_name; /* variable name index in dtdo_strtab */ 357179193Sjb uint32_t dtdv_id; /* variable reference identifier */ 358179193Sjb uint8_t dtdv_kind; /* variable kind (see below) */ 359179193Sjb uint8_t dtdv_scope; /* variable scope (see below) */ 360179193Sjb uint16_t dtdv_flags; /* variable flags (see below) */ 361179193Sjb dtrace_diftype_t dtdv_type; /* variable type (see above) */ 362179193Sjb} dtrace_difv_t; 363179193Sjb 364179193Sjb#define DIFV_KIND_ARRAY 0 /* variable is an array of quantities */ 365179193Sjb#define DIFV_KIND_SCALAR 1 /* variable is a scalar quantity */ 366179193Sjb 367179193Sjb#define DIFV_SCOPE_GLOBAL 0 /* variable has global scope */ 368179193Sjb#define DIFV_SCOPE_THREAD 1 /* variable has thread scope */ 369179193Sjb#define DIFV_SCOPE_LOCAL 2 /* variable has local scope */ 370179193Sjb 371179193Sjb#define DIFV_F_REF 0x1 /* variable is referenced by DIFO */ 372179193Sjb#define DIFV_F_MOD 0x2 /* variable is written by DIFO */ 373179193Sjb 374179193Sjb/* 375179193Sjb * DTrace Actions 376179193Sjb * 377179193Sjb * The upper byte determines the class of the action; the low bytes determines 378179193Sjb * the specific action within that class. The classes of actions are as 379179193Sjb * follows: 380179193Sjb * 381179193Sjb * [ no class ] <= May record process- or kernel-related data 382179193Sjb * DTRACEACT_PROC <= Only records process-related data 383179193Sjb * DTRACEACT_PROC_DESTRUCTIVE <= Potentially destructive to processes 384179193Sjb * DTRACEACT_KERNEL <= Only records kernel-related data 385179193Sjb * DTRACEACT_KERNEL_DESTRUCTIVE <= Potentially destructive to the kernel 386179193Sjb * DTRACEACT_SPECULATIVE <= Speculation-related action 387179193Sjb * DTRACEACT_AGGREGATION <= Aggregating action 388179193Sjb */ 389179193Sjb#define DTRACEACT_NONE 0 /* no action */ 390179193Sjb#define DTRACEACT_DIFEXPR 1 /* action is DIF expression */ 391179193Sjb#define DTRACEACT_EXIT 2 /* exit() action */ 392179193Sjb#define DTRACEACT_PRINTF 3 /* printf() action */ 393179193Sjb#define DTRACEACT_PRINTA 4 /* printa() action */ 394179193Sjb#define DTRACEACT_LIBACT 5 /* library-controlled action */ 395179193Sjb 396179193Sjb#define DTRACEACT_PROC 0x0100 397179193Sjb#define DTRACEACT_USTACK (DTRACEACT_PROC + 1) 398179193Sjb#define DTRACEACT_JSTACK (DTRACEACT_PROC + 2) 399179193Sjb#define DTRACEACT_USYM (DTRACEACT_PROC + 3) 400179193Sjb#define DTRACEACT_UMOD (DTRACEACT_PROC + 4) 401179193Sjb#define DTRACEACT_UADDR (DTRACEACT_PROC + 5) 402179193Sjb 403179193Sjb#define DTRACEACT_PROC_DESTRUCTIVE 0x0200 404179193Sjb#define DTRACEACT_STOP (DTRACEACT_PROC_DESTRUCTIVE + 1) 405179193Sjb#define DTRACEACT_RAISE (DTRACEACT_PROC_DESTRUCTIVE + 2) 406179193Sjb#define DTRACEACT_SYSTEM (DTRACEACT_PROC_DESTRUCTIVE + 3) 407179193Sjb#define DTRACEACT_FREOPEN (DTRACEACT_PROC_DESTRUCTIVE + 4) 408179193Sjb 409179193Sjb#define DTRACEACT_PROC_CONTROL 0x0300 410179193Sjb 411179193Sjb#define DTRACEACT_KERNEL 0x0400 412179193Sjb#define DTRACEACT_STACK (DTRACEACT_KERNEL + 1) 413179193Sjb#define DTRACEACT_SYM (DTRACEACT_KERNEL + 2) 414179193Sjb#define DTRACEACT_MOD (DTRACEACT_KERNEL + 3) 415179193Sjb 416179193Sjb#define DTRACEACT_KERNEL_DESTRUCTIVE 0x0500 417179193Sjb#define DTRACEACT_BREAKPOINT (DTRACEACT_KERNEL_DESTRUCTIVE + 1) 418179193Sjb#define DTRACEACT_PANIC (DTRACEACT_KERNEL_DESTRUCTIVE + 2) 419179193Sjb#define DTRACEACT_CHILL (DTRACEACT_KERNEL_DESTRUCTIVE + 3) 420179193Sjb 421179193Sjb#define DTRACEACT_SPECULATIVE 0x0600 422179193Sjb#define DTRACEACT_SPECULATE (DTRACEACT_SPECULATIVE + 1) 423179193Sjb#define DTRACEACT_COMMIT (DTRACEACT_SPECULATIVE + 2) 424179193Sjb#define DTRACEACT_DISCARD (DTRACEACT_SPECULATIVE + 3) 425179193Sjb 426179193Sjb#define DTRACEACT_CLASS(x) ((x) & 0xff00) 427179193Sjb 428179193Sjb#define DTRACEACT_ISDESTRUCTIVE(x) \ 429179193Sjb (DTRACEACT_CLASS(x) == DTRACEACT_PROC_DESTRUCTIVE || \ 430179193Sjb DTRACEACT_CLASS(x) == DTRACEACT_KERNEL_DESTRUCTIVE) 431179193Sjb 432179193Sjb#define DTRACEACT_ISSPECULATIVE(x) \ 433179193Sjb (DTRACEACT_CLASS(x) == DTRACEACT_SPECULATIVE) 434179193Sjb 435179193Sjb#define DTRACEACT_ISPRINTFLIKE(x) \ 436179193Sjb ((x) == DTRACEACT_PRINTF || (x) == DTRACEACT_PRINTA || \ 437179193Sjb (x) == DTRACEACT_SYSTEM || (x) == DTRACEACT_FREOPEN) 438179193Sjb 439179193Sjb/* 440179193Sjb * DTrace Aggregating Actions 441179193Sjb * 442179193Sjb * These are functions f(x) for which the following is true: 443179193Sjb * 444179193Sjb * f(f(x_0) U f(x_1) U ... U f(x_n)) = f(x_0 U x_1 U ... U x_n) 445179193Sjb * 446179193Sjb * where x_n is a set of arbitrary data. Aggregating actions are in their own 447179193Sjb * DTrace action class, DTTRACEACT_AGGREGATION. The macros provided here allow 448179193Sjb * for easier processing of the aggregation argument and data payload for a few 449179193Sjb * aggregating actions (notably: quantize(), lquantize(), and ustack()). 450179193Sjb */ 451179193Sjb#define DTRACEACT_AGGREGATION 0x0700 452179193Sjb#define DTRACEAGG_COUNT (DTRACEACT_AGGREGATION + 1) 453179193Sjb#define DTRACEAGG_MIN (DTRACEACT_AGGREGATION + 2) 454179193Sjb#define DTRACEAGG_MAX (DTRACEACT_AGGREGATION + 3) 455179193Sjb#define DTRACEAGG_AVG (DTRACEACT_AGGREGATION + 4) 456179193Sjb#define DTRACEAGG_SUM (DTRACEACT_AGGREGATION + 5) 457179193Sjb#define DTRACEAGG_STDDEV (DTRACEACT_AGGREGATION + 6) 458179193Sjb#define DTRACEAGG_QUANTIZE (DTRACEACT_AGGREGATION + 7) 459179193Sjb#define DTRACEAGG_LQUANTIZE (DTRACEACT_AGGREGATION + 8) 460179193Sjb 461179193Sjb#define DTRACEACT_ISAGG(x) \ 462179193Sjb (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION) 463179193Sjb 464179193Sjb#define DTRACE_QUANTIZE_NBUCKETS \ 465179193Sjb (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) 466179193Sjb 467179193Sjb#define DTRACE_QUANTIZE_ZEROBUCKET ((sizeof (uint64_t) * NBBY) - 1) 468179193Sjb 469179193Sjb#define DTRACE_QUANTIZE_BUCKETVAL(buck) \ 470179193Sjb (int64_t)((buck) < DTRACE_QUANTIZE_ZEROBUCKET ? \ 471179193Sjb -(1LL << (DTRACE_QUANTIZE_ZEROBUCKET - 1 - (buck))) : \ 472179193Sjb (buck) == DTRACE_QUANTIZE_ZEROBUCKET ? 0 : \ 473179193Sjb 1LL << ((buck) - DTRACE_QUANTIZE_ZEROBUCKET - 1)) 474179193Sjb 475179193Sjb#define DTRACE_LQUANTIZE_STEPSHIFT 48 476179193Sjb#define DTRACE_LQUANTIZE_STEPMASK ((uint64_t)UINT16_MAX << 48) 477179193Sjb#define DTRACE_LQUANTIZE_LEVELSHIFT 32 478179193Sjb#define DTRACE_LQUANTIZE_LEVELMASK ((uint64_t)UINT16_MAX << 32) 479179193Sjb#define DTRACE_LQUANTIZE_BASESHIFT 0 480179193Sjb#define DTRACE_LQUANTIZE_BASEMASK UINT32_MAX 481179193Sjb 482179193Sjb#define DTRACE_LQUANTIZE_STEP(x) \ 483179193Sjb (uint16_t)(((x) & DTRACE_LQUANTIZE_STEPMASK) >> \ 484179193Sjb DTRACE_LQUANTIZE_STEPSHIFT) 485179193Sjb 486179193Sjb#define DTRACE_LQUANTIZE_LEVELS(x) \ 487179193Sjb (uint16_t)(((x) & DTRACE_LQUANTIZE_LEVELMASK) >> \ 488179193Sjb DTRACE_LQUANTIZE_LEVELSHIFT) 489179193Sjb 490179193Sjb#define DTRACE_LQUANTIZE_BASE(x) \ 491179193Sjb (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \ 492179193Sjb DTRACE_LQUANTIZE_BASESHIFT) 493179193Sjb 494179193Sjb#define DTRACE_USTACK_NFRAMES(x) (uint32_t)((x) & UINT32_MAX) 495179193Sjb#define DTRACE_USTACK_STRSIZE(x) (uint32_t)((x) >> 32) 496179193Sjb#define DTRACE_USTACK_ARG(x, y) \ 497179193Sjb ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) 498179193Sjb 499179193Sjb#ifndef _LP64 500179193Sjb#ifndef _LITTLE_ENDIAN 501179193Sjb#define DTRACE_PTR(type, name) uint32_t name##pad; type *name 502179193Sjb#else 503179193Sjb#define DTRACE_PTR(type, name) type *name; uint32_t name##pad 504179193Sjb#endif 505179193Sjb#else 506179193Sjb#define DTRACE_PTR(type, name) type *name 507179193Sjb#endif 508179193Sjb 509179193Sjb/* 510179193Sjb * DTrace Object Format (DOF) 511179193Sjb * 512179193Sjb * DTrace programs can be persistently encoded in the DOF format so that they 513179193Sjb * may be embedded in other programs (for example, in an ELF file) or in the 514179193Sjb * dtrace driver configuration file for use in anonymous tracing. The DOF 515179193Sjb * format is versioned and extensible so that it can be revised and so that 516179193Sjb * internal data structures can be modified or extended compatibly. All DOF 517179193Sjb * structures use fixed-size types, so the 32-bit and 64-bit representations 518179193Sjb * are identical and consumers can use either data model transparently. 519179193Sjb * 520179193Sjb * The file layout is structured as follows: 521179193Sjb * 522179193Sjb * +---------------+-------------------+----- ... ----+---- ... ------+ 523179193Sjb * | dof_hdr_t | dof_sec_t[ ... ] | loadable | non-loadable | 524179193Sjb * | (file header) | (section headers) | section data | section data | 525179193Sjb * +---------------+-------------------+----- ... ----+---- ... ------+ 526179193Sjb * |<------------ dof_hdr.dofh_loadsz --------------->| | 527179193Sjb * |<------------ dof_hdr.dofh_filesz ------------------------------->| 528179193Sjb * 529179193Sjb * The file header stores meta-data including a magic number, data model for 530179193Sjb * the instrumentation, data encoding, and properties of the DIF code within. 531179193Sjb * The header describes its own size and the size of the section headers. By 532179193Sjb * convention, an array of section headers follows the file header, and then 533179193Sjb * the data for all loadable sections and unloadable sections. This permits 534179193Sjb * consumer code to easily download the headers and all loadable data into the 535179193Sjb * DTrace driver in one contiguous chunk, omitting other extraneous sections. 536179193Sjb * 537179193Sjb * The section headers describe the size, offset, alignment, and section type 538179193Sjb * for each section. Sections are described using a set of #defines that tell 539179193Sjb * the consumer what kind of data is expected. Sections can contain links to 540179193Sjb * other sections by storing a dof_secidx_t, an index into the section header 541179193Sjb * array, inside of the section data structures. The section header includes 542179193Sjb * an entry size so that sections with data arrays can grow their structures. 543179193Sjb * 544179193Sjb * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which 545179193Sjb * are represented themselves as a collection of related DOF sections. This 546179193Sjb * permits us to change the set of sections associated with a DIFO over time, 547179193Sjb * and also permits us to encode DIFOs that contain different sets of sections. 548179193Sjb * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a 549179193Sjb * section of type DOF_SECT_DIFOHDR. This section's data is then an array of 550179193Sjb * dof_secidx_t's which in turn denote the sections associated with this DIFO. 551179193Sjb * 552179193Sjb * This loose coupling of the file structure (header and sections) to the 553179193Sjb * structure of the DTrace program itself (ECB descriptions, action 554179193Sjb * descriptions, and DIFOs) permits activities such as relocation processing 555179193Sjb * to occur in a single pass without having to understand D program structure. 556179193Sjb * 557179193Sjb * Finally, strings are always stored in ELF-style string tables along with a 558179193Sjb * string table section index and string table offset. Therefore strings in 559179193Sjb * DOF are always arbitrary-length and not bound to the current implementation. 560179193Sjb */ 561179193Sjb 562179193Sjb#define DOF_ID_SIZE 16 /* total size of dofh_ident[] in bytes */ 563179193Sjb 564179193Sjbtypedef struct dof_hdr { 565179193Sjb uint8_t dofh_ident[DOF_ID_SIZE]; /* identification bytes (see below) */ 566179193Sjb uint32_t dofh_flags; /* file attribute flags (if any) */ 567179193Sjb uint32_t dofh_hdrsize; /* size of file header in bytes */ 568179193Sjb uint32_t dofh_secsize; /* size of section header in bytes */ 569179193Sjb uint32_t dofh_secnum; /* number of section headers */ 570179193Sjb uint64_t dofh_secoff; /* file offset of section headers */ 571179193Sjb uint64_t dofh_loadsz; /* file size of loadable portion */ 572179193Sjb uint64_t dofh_filesz; /* file size of entire DOF file */ 573179193Sjb uint64_t dofh_pad; /* reserved for future use */ 574179193Sjb} dof_hdr_t; 575179193Sjb 576179193Sjb#define DOF_ID_MAG0 0 /* first byte of magic number */ 577179193Sjb#define DOF_ID_MAG1 1 /* second byte of magic number */ 578179193Sjb#define DOF_ID_MAG2 2 /* third byte of magic number */ 579179193Sjb#define DOF_ID_MAG3 3 /* fourth byte of magic number */ 580179193Sjb#define DOF_ID_MODEL 4 /* DOF data model (see below) */ 581179193Sjb#define DOF_ID_ENCODING 5 /* DOF data encoding (see below) */ 582179193Sjb#define DOF_ID_VERSION 6 /* DOF file format major version (see below) */ 583179193Sjb#define DOF_ID_DIFVERS 7 /* DIF instruction set version */ 584179193Sjb#define DOF_ID_DIFIREG 8 /* DIF integer registers used by compiler */ 585179193Sjb#define DOF_ID_DIFTREG 9 /* DIF tuple registers used by compiler */ 586179193Sjb#define DOF_ID_PAD 10 /* start of padding bytes (all zeroes) */ 587179193Sjb 588179193Sjb#define DOF_MAG_MAG0 0x7F /* DOF_ID_MAG[0-3] */ 589179193Sjb#define DOF_MAG_MAG1 'D' 590179193Sjb#define DOF_MAG_MAG2 'O' 591179193Sjb#define DOF_MAG_MAG3 'F' 592179193Sjb 593179193Sjb#define DOF_MAG_STRING "\177DOF" 594179193Sjb#define DOF_MAG_STRLEN 4 595179193Sjb 596179193Sjb#define DOF_MODEL_NONE 0 /* DOF_ID_MODEL */ 597179193Sjb#define DOF_MODEL_ILP32 1 598179193Sjb#define DOF_MODEL_LP64 2 599179193Sjb 600179193Sjb#ifdef _LP64 601179193Sjb#define DOF_MODEL_NATIVE DOF_MODEL_LP64 602179193Sjb#else 603179193Sjb#define DOF_MODEL_NATIVE DOF_MODEL_ILP32 604179193Sjb#endif 605179193Sjb 606179193Sjb#define DOF_ENCODE_NONE 0 /* DOF_ID_ENCODING */ 607179193Sjb#define DOF_ENCODE_LSB 1 608179193Sjb#define DOF_ENCODE_MSB 2 609179193Sjb 610179193Sjb#ifdef _BIG_ENDIAN 611179193Sjb#define DOF_ENCODE_NATIVE DOF_ENCODE_MSB 612179193Sjb#else 613179193Sjb#define DOF_ENCODE_NATIVE DOF_ENCODE_LSB 614179193Sjb#endif 615179193Sjb 616179193Sjb#define DOF_VERSION_1 1 /* DOF version 1: Solaris 10 FCS */ 617179193Sjb#define DOF_VERSION_2 2 /* DOF version 2: Solaris Express 6/06 */ 618179193Sjb#define DOF_VERSION DOF_VERSION_2 /* Latest DOF version */ 619179193Sjb 620179193Sjb#define DOF_FL_VALID 0 /* mask of all valid dofh_flags bits */ 621179193Sjb 622179193Sjbtypedef uint32_t dof_secidx_t; /* section header table index type */ 623179193Sjbtypedef uint32_t dof_stridx_t; /* string table index type */ 624179193Sjb 625179193Sjb#define DOF_SECIDX_NONE (-1U) /* null value for section indices */ 626179193Sjb#define DOF_STRIDX_NONE (-1U) /* null value for string indices */ 627179193Sjb 628179193Sjbtypedef struct dof_sec { 629179193Sjb uint32_t dofs_type; /* section type (see below) */ 630179193Sjb uint32_t dofs_align; /* section data memory alignment */ 631179193Sjb uint32_t dofs_flags; /* section flags (if any) */ 632179193Sjb uint32_t dofs_entsize; /* size of section entry (if table) */ 633179193Sjb uint64_t dofs_offset; /* offset of section data within file */ 634179193Sjb uint64_t dofs_size; /* size of section data in bytes */ 635179193Sjb} dof_sec_t; 636179193Sjb 637179193Sjb#define DOF_SECT_NONE 0 /* null section */ 638179193Sjb#define DOF_SECT_COMMENTS 1 /* compiler comments */ 639179193Sjb#define DOF_SECT_SOURCE 2 /* D program source code */ 640179193Sjb#define DOF_SECT_ECBDESC 3 /* dof_ecbdesc_t */ 641179193Sjb#define DOF_SECT_PROBEDESC 4 /* dof_probedesc_t */ 642179193Sjb#define DOF_SECT_ACTDESC 5 /* dof_actdesc_t array */ 643179193Sjb#define DOF_SECT_DIFOHDR 6 /* dof_difohdr_t (variable length) */ 644179193Sjb#define DOF_SECT_DIF 7 /* uint32_t array of byte code */ 645179193Sjb#define DOF_SECT_STRTAB 8 /* string table */ 646179193Sjb#define DOF_SECT_VARTAB 9 /* dtrace_difv_t array */ 647179193Sjb#define DOF_SECT_RELTAB 10 /* dof_relodesc_t array */ 648179193Sjb#define DOF_SECT_TYPTAB 11 /* dtrace_diftype_t array */ 649179193Sjb#define DOF_SECT_URELHDR 12 /* dof_relohdr_t (user relocations) */ 650179193Sjb#define DOF_SECT_KRELHDR 13 /* dof_relohdr_t (kernel relocations) */ 651179193Sjb#define DOF_SECT_OPTDESC 14 /* dof_optdesc_t array */ 652179193Sjb#define DOF_SECT_PROVIDER 15 /* dof_provider_t */ 653179193Sjb#define DOF_SECT_PROBES 16 /* dof_probe_t array */ 654179193Sjb#define DOF_SECT_PRARGS 17 /* uint8_t array (probe arg mappings) */ 655179193Sjb#define DOF_SECT_PROFFS 18 /* uint32_t array (probe arg offsets) */ 656179193Sjb#define DOF_SECT_INTTAB 19 /* uint64_t array */ 657179193Sjb#define DOF_SECT_UTSNAME 20 /* struct utsname */ 658179193Sjb#define DOF_SECT_XLTAB 21 /* dof_xlref_t array */ 659179193Sjb#define DOF_SECT_XLMEMBERS 22 /* dof_xlmember_t array */ 660179193Sjb#define DOF_SECT_XLIMPORT 23 /* dof_xlator_t */ 661179193Sjb#define DOF_SECT_XLEXPORT 24 /* dof_xlator_t */ 662179193Sjb#define DOF_SECT_PREXPORT 25 /* dof_secidx_t array (exported objs) */ 663179193Sjb#define DOF_SECT_PRENOFFS 26 /* uint32_t array (enabled offsets) */ 664179193Sjb 665179193Sjb#define DOF_SECF_LOAD 1 /* section should be loaded */ 666179193Sjb 667179193Sjbtypedef struct dof_ecbdesc { 668179193Sjb dof_secidx_t dofe_probes; /* link to DOF_SECT_PROBEDESC */ 669179193Sjb dof_secidx_t dofe_pred; /* link to DOF_SECT_DIFOHDR */ 670179193Sjb dof_secidx_t dofe_actions; /* link to DOF_SECT_ACTDESC */ 671179193Sjb uint32_t dofe_pad; /* reserved for future use */ 672179193Sjb uint64_t dofe_uarg; /* user-supplied library argument */ 673179193Sjb} dof_ecbdesc_t; 674179193Sjb 675179193Sjbtypedef struct dof_probedesc { 676179193Sjb dof_secidx_t dofp_strtab; /* link to DOF_SECT_STRTAB section */ 677179193Sjb dof_stridx_t dofp_provider; /* provider string */ 678179193Sjb dof_stridx_t dofp_mod; /* module string */ 679179193Sjb dof_stridx_t dofp_func; /* function string */ 680179193Sjb dof_stridx_t dofp_name; /* name string */ 681179193Sjb uint32_t dofp_id; /* probe identifier (or zero) */ 682179193Sjb} dof_probedesc_t; 683179193Sjb 684179193Sjbtypedef struct dof_actdesc { 685179193Sjb dof_secidx_t dofa_difo; /* link to DOF_SECT_DIFOHDR */ 686179193Sjb dof_secidx_t dofa_strtab; /* link to DOF_SECT_STRTAB section */ 687179193Sjb uint32_t dofa_kind; /* action kind (DTRACEACT_* constant) */ 688179193Sjb uint32_t dofa_ntuple; /* number of subsequent tuple actions */ 689179193Sjb uint64_t dofa_arg; /* kind-specific argument */ 690179193Sjb uint64_t dofa_uarg; /* user-supplied argument */ 691179193Sjb} dof_actdesc_t; 692179193Sjb 693179193Sjbtypedef struct dof_difohdr { 694179193Sjb dtrace_diftype_t dofd_rtype; /* return type for this fragment */ 695179193Sjb dof_secidx_t dofd_links[1]; /* variable length array of indices */ 696179193Sjb} dof_difohdr_t; 697179193Sjb 698179193Sjbtypedef struct dof_relohdr { 699179193Sjb dof_secidx_t dofr_strtab; /* link to DOF_SECT_STRTAB for names */ 700179193Sjb dof_secidx_t dofr_relsec; /* link to DOF_SECT_RELTAB for relos */ 701179193Sjb dof_secidx_t dofr_tgtsec; /* link to section we are relocating */ 702179193Sjb} dof_relohdr_t; 703179193Sjb 704179193Sjbtypedef struct dof_relodesc { 705179193Sjb dof_stridx_t dofr_name; /* string name of relocation symbol */ 706179193Sjb uint32_t dofr_type; /* relo type (DOF_RELO_* constant) */ 707179193Sjb uint64_t dofr_offset; /* byte offset for relocation */ 708179193Sjb uint64_t dofr_data; /* additional type-specific data */ 709179193Sjb} dof_relodesc_t; 710179193Sjb 711179193Sjb#define DOF_RELO_NONE 0 /* empty relocation entry */ 712179193Sjb#define DOF_RELO_SETX 1 /* relocate setx value */ 713179193Sjb 714179193Sjbtypedef struct dof_optdesc { 715179193Sjb uint32_t dofo_option; /* option identifier */ 716179193Sjb dof_secidx_t dofo_strtab; /* string table, if string option */ 717179193Sjb uint64_t dofo_value; /* option value or string index */ 718179193Sjb} dof_optdesc_t; 719179193Sjb 720179193Sjbtypedef uint32_t dof_attr_t; /* encoded stability attributes */ 721179193Sjb 722179193Sjb#define DOF_ATTR(n, d, c) (((n) << 24) | ((d) << 16) | ((c) << 8)) 723179193Sjb#define DOF_ATTR_NAME(a) (((a) >> 24) & 0xff) 724179193Sjb#define DOF_ATTR_DATA(a) (((a) >> 16) & 0xff) 725179193Sjb#define DOF_ATTR_CLASS(a) (((a) >> 8) & 0xff) 726179193Sjb 727179193Sjbtypedef struct dof_provider { 728179193Sjb dof_secidx_t dofpv_strtab; /* link to DOF_SECT_STRTAB section */ 729179193Sjb dof_secidx_t dofpv_probes; /* link to DOF_SECT_PROBES section */ 730179193Sjb dof_secidx_t dofpv_prargs; /* link to DOF_SECT_PRARGS section */ 731179193Sjb dof_secidx_t dofpv_proffs; /* link to DOF_SECT_PROFFS section */ 732179193Sjb dof_stridx_t dofpv_name; /* provider name string */ 733179193Sjb dof_attr_t dofpv_provattr; /* provider attributes */ 734179193Sjb dof_attr_t dofpv_modattr; /* module attributes */ 735179193Sjb dof_attr_t dofpv_funcattr; /* function attributes */ 736179193Sjb dof_attr_t dofpv_nameattr; /* name attributes */ 737179193Sjb dof_attr_t dofpv_argsattr; /* args attributes */ 738179193Sjb dof_secidx_t dofpv_prenoffs; /* link to DOF_SECT_PRENOFFS section */ 739179193Sjb} dof_provider_t; 740179193Sjb 741179193Sjbtypedef struct dof_probe { 742179193Sjb uint64_t dofpr_addr; /* probe base address or offset */ 743179193Sjb dof_stridx_t dofpr_func; /* probe function string */ 744179193Sjb dof_stridx_t dofpr_name; /* probe name string */ 745179193Sjb dof_stridx_t dofpr_nargv; /* native argument type strings */ 746179193Sjb dof_stridx_t dofpr_xargv; /* translated argument type strings */ 747179193Sjb uint32_t dofpr_argidx; /* index of first argument mapping */ 748179193Sjb uint32_t dofpr_offidx; /* index of first offset entry */ 749179193Sjb uint8_t dofpr_nargc; /* native argument count */ 750179193Sjb uint8_t dofpr_xargc; /* translated argument count */ 751179193Sjb uint16_t dofpr_noffs; /* number of offset entries for probe */ 752179193Sjb uint32_t dofpr_enoffidx; /* index of first is-enabled offset */ 753179193Sjb uint16_t dofpr_nenoffs; /* number of is-enabled offsets */ 754179193Sjb uint16_t dofpr_pad1; /* reserved for future use */ 755179193Sjb uint32_t dofpr_pad2; /* reserved for future use */ 756179193Sjb} dof_probe_t; 757179193Sjb 758179193Sjbtypedef struct dof_xlator { 759179193Sjb dof_secidx_t dofxl_members; /* link to DOF_SECT_XLMEMBERS section */ 760179193Sjb dof_secidx_t dofxl_strtab; /* link to DOF_SECT_STRTAB section */ 761179193Sjb dof_stridx_t dofxl_argv; /* input parameter type strings */ 762179193Sjb uint32_t dofxl_argc; /* input parameter list length */ 763179193Sjb dof_stridx_t dofxl_type; /* output type string name */ 764179193Sjb dof_attr_t dofxl_attr; /* output stability attributes */ 765179193Sjb} dof_xlator_t; 766179193Sjb 767179193Sjbtypedef struct dof_xlmember { 768179193Sjb dof_secidx_t dofxm_difo; /* member link to DOF_SECT_DIFOHDR */ 769179193Sjb dof_stridx_t dofxm_name; /* member name */ 770179193Sjb dtrace_diftype_t dofxm_type; /* member type */ 771179193Sjb} dof_xlmember_t; 772179193Sjb 773179193Sjbtypedef struct dof_xlref { 774179193Sjb dof_secidx_t dofxr_xlator; /* link to DOF_SECT_XLATORS section */ 775179193Sjb uint32_t dofxr_member; /* index of referenced dof_xlmember */ 776179193Sjb uint32_t dofxr_argn; /* index of argument for DIF_OP_XLARG */ 777179193Sjb} dof_xlref_t; 778179193Sjb 779179193Sjb/* 780179193Sjb * DTrace Intermediate Format Object (DIFO) 781179193Sjb * 782179193Sjb * A DIFO is used to store the compiled DIF for a D expression, its return 783179193Sjb * type, and its string and variable tables. The string table is a single 784179193Sjb * buffer of character data into which sets instructions and variable 785179193Sjb * references can reference strings using a byte offset. The variable table 786179193Sjb * is an array of dtrace_difv_t structures that describe the name and type of 787179193Sjb * each variable and the id used in the DIF code. This structure is described 788179193Sjb * above in the DIF section of this header file. The DIFO is used at both 789179193Sjb * user-level (in the library) and in the kernel, but the structure is never 790179193Sjb * passed between the two: the DOF structures form the only interface. As a 791179193Sjb * result, the definition can change depending on the presence of _KERNEL. 792179193Sjb */ 793179193Sjbtypedef struct dtrace_difo { 794179193Sjb dif_instr_t *dtdo_buf; /* instruction buffer */ 795179193Sjb uint64_t *dtdo_inttab; /* integer table (optional) */ 796179193Sjb char *dtdo_strtab; /* string table (optional) */ 797179193Sjb dtrace_difv_t *dtdo_vartab; /* variable table (optional) */ 798179193Sjb uint_t dtdo_len; /* length of instruction buffer */ 799179193Sjb uint_t dtdo_intlen; /* length of integer table */ 800179193Sjb uint_t dtdo_strlen; /* length of string table */ 801179193Sjb uint_t dtdo_varlen; /* length of variable table */ 802179193Sjb dtrace_diftype_t dtdo_rtype; /* return type */ 803179193Sjb uint_t dtdo_refcnt; /* owner reference count */ 804179193Sjb uint_t dtdo_destructive; /* invokes destructive subroutines */ 805179193Sjb#ifndef _KERNEL 806179193Sjb dof_relodesc_t *dtdo_kreltab; /* kernel relocations */ 807179193Sjb dof_relodesc_t *dtdo_ureltab; /* user relocations */ 808179193Sjb struct dt_node **dtdo_xlmtab; /* translator references */ 809179193Sjb uint_t dtdo_krelen; /* length of krelo table */ 810179193Sjb uint_t dtdo_urelen; /* length of urelo table */ 811179193Sjb uint_t dtdo_xlmlen; /* length of translator table */ 812179193Sjb#endif 813179193Sjb} dtrace_difo_t; 814179193Sjb 815179193Sjb/* 816179193Sjb * DTrace Enabling Description Structures 817179193Sjb * 818179193Sjb * When DTrace is tracking the description of a DTrace enabling entity (probe, 819179193Sjb * predicate, action, ECB, record, etc.), it does so in a description 820179193Sjb * structure. These structures all end in "desc", and are used at both 821179193Sjb * user-level and in the kernel -- but (with the exception of 822179193Sjb * dtrace_probedesc_t) they are never passed between them. Typically, 823179193Sjb * user-level will use the description structures when assembling an enabling. 824179193Sjb * It will then distill those description structures into a DOF object (see 825179193Sjb * above), and send it into the kernel. The kernel will again use the 826179193Sjb * description structures to create a description of the enabling as it reads 827179193Sjb * the DOF. When the description is complete, the enabling will be actually 828179193Sjb * created -- turning it into the structures that represent the enabling 829179193Sjb * instead of merely describing it. Not surprisingly, the description 830179193Sjb * structures bear a strong resemblance to the DOF structures that act as their 831179193Sjb * conduit. 832179193Sjb */ 833179193Sjbstruct dtrace_predicate; 834179193Sjb 835179193Sjbtypedef struct dtrace_probedesc { 836179193Sjb dtrace_id_t dtpd_id; /* probe identifier */ 837179193Sjb char dtpd_provider[DTRACE_PROVNAMELEN]; /* probe provider name */ 838179193Sjb char dtpd_mod[DTRACE_MODNAMELEN]; /* probe module name */ 839179193Sjb char dtpd_func[DTRACE_FUNCNAMELEN]; /* probe function name */ 840179193Sjb char dtpd_name[DTRACE_NAMELEN]; /* probe name */ 841179193Sjb} dtrace_probedesc_t; 842179193Sjb 843179193Sjbtypedef struct dtrace_repldesc { 844179193Sjb dtrace_probedesc_t dtrpd_match; /* probe descr. to match */ 845179193Sjb dtrace_probedesc_t dtrpd_create; /* probe descr. to create */ 846179193Sjb} dtrace_repldesc_t; 847179193Sjb 848179193Sjbtypedef struct dtrace_preddesc { 849179193Sjb dtrace_difo_t *dtpdd_difo; /* pointer to DIF object */ 850179193Sjb struct dtrace_predicate *dtpdd_predicate; /* pointer to predicate */ 851179193Sjb} dtrace_preddesc_t; 852179193Sjb 853179193Sjbtypedef struct dtrace_actdesc { 854179193Sjb dtrace_difo_t *dtad_difo; /* pointer to DIF object */ 855179193Sjb struct dtrace_actdesc *dtad_next; /* next action */ 856179193Sjb dtrace_actkind_t dtad_kind; /* kind of action */ 857179193Sjb uint32_t dtad_ntuple; /* number in tuple */ 858179193Sjb uint64_t dtad_arg; /* action argument */ 859179193Sjb uint64_t dtad_uarg; /* user argument */ 860179193Sjb int dtad_refcnt; /* reference count */ 861179193Sjb} dtrace_actdesc_t; 862179193Sjb 863179193Sjbtypedef struct dtrace_ecbdesc { 864179193Sjb dtrace_actdesc_t *dted_action; /* action description(s) */ 865179193Sjb dtrace_preddesc_t dted_pred; /* predicate description */ 866179193Sjb dtrace_probedesc_t dted_probe; /* probe description */ 867179193Sjb uint64_t dted_uarg; /* library argument */ 868179193Sjb int dted_refcnt; /* reference count */ 869179193Sjb} dtrace_ecbdesc_t; 870179193Sjb 871179193Sjb/* 872179193Sjb * DTrace Metadata Description Structures 873179193Sjb * 874179193Sjb * DTrace separates the trace data stream from the metadata stream. The only 875179193Sjb * metadata tokens placed in the data stream are enabled probe identifiers 876179193Sjb * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order 877179193Sjb * to determine the structure of the data, DTrace consumers pass the token to 878179193Sjb * the kernel, and receive in return a corresponding description of the enabled 879179193Sjb * probe (via the dtrace_eprobedesc structure) or the aggregation (via the 880179193Sjb * dtrace_aggdesc structure). Both of these structures are expressed in terms 881179193Sjb * of record descriptions (via the dtrace_recdesc structure) that describe the 882179193Sjb * exact structure of the data. Some record descriptions may also contain a 883179193Sjb * format identifier; this additional bit of metadata can be retrieved from the 884179193Sjb * kernel, for which a format description is returned via the dtrace_fmtdesc 885179193Sjb * structure. Note that all four of these structures must be bitness-neutral 886179193Sjb * to allow for a 32-bit DTrace consumer on a 64-bit kernel. 887179193Sjb */ 888179193Sjbtypedef struct dtrace_recdesc { 889179193Sjb dtrace_actkind_t dtrd_action; /* kind of action */ 890179193Sjb uint32_t dtrd_size; /* size of record */ 891179193Sjb uint32_t dtrd_offset; /* offset in ECB's data */ 892179193Sjb uint16_t dtrd_alignment; /* required alignment */ 893179193Sjb uint16_t dtrd_format; /* format, if any */ 894179193Sjb uint64_t dtrd_arg; /* action argument */ 895179193Sjb uint64_t dtrd_uarg; /* user argument */ 896179193Sjb} dtrace_recdesc_t; 897179193Sjb 898179193Sjbtypedef struct dtrace_eprobedesc { 899179193Sjb dtrace_epid_t dtepd_epid; /* enabled probe ID */ 900179193Sjb dtrace_id_t dtepd_probeid; /* probe ID */ 901179193Sjb uint64_t dtepd_uarg; /* library argument */ 902179193Sjb uint32_t dtepd_size; /* total size */ 903179193Sjb int dtepd_nrecs; /* number of records */ 904179193Sjb dtrace_recdesc_t dtepd_rec[1]; /* records themselves */ 905179193Sjb} dtrace_eprobedesc_t; 906179193Sjb 907179193Sjbtypedef struct dtrace_aggdesc { 908179193Sjb DTRACE_PTR(char, dtagd_name); /* not filled in by kernel */ 909179193Sjb dtrace_aggvarid_t dtagd_varid; /* not filled in by kernel */ 910179193Sjb int dtagd_flags; /* not filled in by kernel */ 911179193Sjb dtrace_aggid_t dtagd_id; /* aggregation ID */ 912179193Sjb dtrace_epid_t dtagd_epid; /* enabled probe ID */ 913179193Sjb uint32_t dtagd_size; /* size in bytes */ 914179193Sjb int dtagd_nrecs; /* number of records */ 915179193Sjb uint32_t dtagd_pad; /* explicit padding */ 916179193Sjb dtrace_recdesc_t dtagd_rec[1]; /* record descriptions */ 917179193Sjb} dtrace_aggdesc_t; 918179193Sjb 919179193Sjbtypedef struct dtrace_fmtdesc { 920179193Sjb DTRACE_PTR(char, dtfd_string); /* format string */ 921179193Sjb int dtfd_length; /* length of format string */ 922179193Sjb uint16_t dtfd_format; /* format identifier */ 923179193Sjb} dtrace_fmtdesc_t; 924179193Sjb 925179193Sjb#define DTRACE_SIZEOF_EPROBEDESC(desc) \ 926179193Sjb (sizeof (dtrace_eprobedesc_t) + ((desc)->dtepd_nrecs ? \ 927179193Sjb (((desc)->dtepd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 928179193Sjb 929179193Sjb#define DTRACE_SIZEOF_AGGDESC(desc) \ 930179193Sjb (sizeof (dtrace_aggdesc_t) + ((desc)->dtagd_nrecs ? \ 931179193Sjb (((desc)->dtagd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 932179193Sjb 933179193Sjb/* 934179193Sjb * DTrace Option Interface 935179193Sjb * 936179193Sjb * Run-time DTrace options are set and retrieved via DOF_SECT_OPTDESC sections 937179193Sjb * in a DOF image. The dof_optdesc structure contains an option identifier and 938179193Sjb * an option value. The valid option identifiers are found below; the mapping 939179193Sjb * between option identifiers and option identifying strings is maintained at 940179193Sjb * user-level. Note that the value of DTRACEOPT_UNSET is such that all of the 941179193Sjb * following are potentially valid option values: all positive integers, zero 942179193Sjb * and negative one. Some options (notably "bufpolicy" and "bufresize") take 943179193Sjb * predefined tokens as their values; these are defined with 944179193Sjb * DTRACEOPT_{option}_{token}. 945179193Sjb */ 946179193Sjb#define DTRACEOPT_BUFSIZE 0 /* buffer size */ 947179193Sjb#define DTRACEOPT_BUFPOLICY 1 /* buffer policy */ 948179193Sjb#define DTRACEOPT_DYNVARSIZE 2 /* dynamic variable size */ 949179193Sjb#define DTRACEOPT_AGGSIZE 3 /* aggregation size */ 950179193Sjb#define DTRACEOPT_SPECSIZE 4 /* speculation size */ 951179193Sjb#define DTRACEOPT_NSPEC 5 /* number of speculations */ 952179193Sjb#define DTRACEOPT_STRSIZE 6 /* string size */ 953179193Sjb#define DTRACEOPT_CLEANRATE 7 /* dynvar cleaning rate */ 954179193Sjb#define DTRACEOPT_CPU 8 /* CPU to trace */ 955179193Sjb#define DTRACEOPT_BUFRESIZE 9 /* buffer resizing policy */ 956179193Sjb#define DTRACEOPT_GRABANON 10 /* grab anonymous state, if any */ 957179193Sjb#define DTRACEOPT_FLOWINDENT 11 /* indent function entry/return */ 958179193Sjb#define DTRACEOPT_QUIET 12 /* only output explicitly traced data */ 959179193Sjb#define DTRACEOPT_STACKFRAMES 13 /* number of stack frames */ 960179193Sjb#define DTRACEOPT_USTACKFRAMES 14 /* number of user stack frames */ 961179193Sjb#define DTRACEOPT_AGGRATE 15 /* aggregation snapshot rate */ 962179193Sjb#define DTRACEOPT_SWITCHRATE 16 /* buffer switching rate */ 963179193Sjb#define DTRACEOPT_STATUSRATE 17 /* status rate */ 964179193Sjb#define DTRACEOPT_DESTRUCTIVE 18 /* destructive actions allowed */ 965179193Sjb#define DTRACEOPT_STACKINDENT 19 /* output indent for stack traces */ 966179193Sjb#define DTRACEOPT_RAWBYTES 20 /* always print bytes in raw form */ 967179193Sjb#define DTRACEOPT_JSTACKFRAMES 21 /* number of jstack() frames */ 968179193Sjb#define DTRACEOPT_JSTACKSTRSIZE 22 /* size of jstack() string table */ 969179193Sjb#define DTRACEOPT_AGGSORTKEY 23 /* sort aggregations by key */ 970179193Sjb#define DTRACEOPT_AGGSORTREV 24 /* reverse-sort aggregations */ 971179193Sjb#define DTRACEOPT_AGGSORTPOS 25 /* agg. position to sort on */ 972179193Sjb#define DTRACEOPT_AGGSORTKEYPOS 26 /* agg. key position to sort on */ 973179193Sjb#define DTRACEOPT_MAX 27 /* number of options */ 974179193Sjb 975179193Sjb#define DTRACEOPT_UNSET (dtrace_optval_t)-2 /* unset option */ 976179193Sjb 977179193Sjb#define DTRACEOPT_BUFPOLICY_RING 0 /* ring buffer */ 978179193Sjb#define DTRACEOPT_BUFPOLICY_FILL 1 /* fill buffer, then stop */ 979179193Sjb#define DTRACEOPT_BUFPOLICY_SWITCH 2 /* switch buffers */ 980179193Sjb 981179193Sjb#define DTRACEOPT_BUFRESIZE_AUTO 0 /* automatic resizing */ 982179193Sjb#define DTRACEOPT_BUFRESIZE_MANUAL 1 /* manual resizing */ 983179193Sjb 984179193Sjb/* 985179193Sjb * DTrace Buffer Interface 986179193Sjb * 987179193Sjb * In order to get a snapshot of the principal or aggregation buffer, 988179193Sjb * user-level passes a buffer description to the kernel with the dtrace_bufdesc 989179193Sjb * structure. This describes which CPU user-level is interested in, and 990179193Sjb * where user-level wishes the kernel to snapshot the buffer to (the 991179193Sjb * dtbd_data field). The kernel uses the same structure to pass back some 992179193Sjb * information regarding the buffer: the size of data actually copied out, the 993179193Sjb * number of drops, the number of errors, and the offset of the oldest record. 994179193Sjb * If the buffer policy is a "switch" policy, taking a snapshot of the 995179193Sjb * principal buffer has the additional effect of switching the active and 996179193Sjb * inactive buffers. Taking a snapshot of the aggregation buffer _always_ has 997179193Sjb * the additional effect of switching the active and inactive buffers. 998179193Sjb */ 999179193Sjbtypedef struct dtrace_bufdesc { 1000179193Sjb uint64_t dtbd_size; /* size of buffer */ 1001179193Sjb uint32_t dtbd_cpu; /* CPU or DTRACE_CPUALL */ 1002179193Sjb uint32_t dtbd_errors; /* number of errors */ 1003179193Sjb uint64_t dtbd_drops; /* number of drops */ 1004179193Sjb DTRACE_PTR(char, dtbd_data); /* data */ 1005179193Sjb uint64_t dtbd_oldest; /* offset of oldest record */ 1006179193Sjb} dtrace_bufdesc_t; 1007179193Sjb 1008179193Sjb/* 1009179193Sjb * DTrace Status 1010179193Sjb * 1011179193Sjb * The status of DTrace is relayed via the dtrace_status structure. This 1012179193Sjb * structure contains members to count drops other than the capacity drops 1013179193Sjb * available via the buffer interface (see above). This consists of dynamic 1014179193Sjb * drops (including capacity dynamic drops, rinsing drops and dirty drops), and 1015179193Sjb * speculative drops (including capacity speculative drops, drops due to busy 1016179193Sjb * speculative buffers and drops due to unavailable speculative buffers). 1017179193Sjb * Additionally, the status structure contains a field to indicate the number 1018179193Sjb * of "fill"-policy buffers have been filled and a boolean field to indicate 1019179193Sjb * that exit() has been called. If the dtst_exiting field is non-zero, no 1020179193Sjb * further data will be generated until tracing is stopped (at which time any 1021179193Sjb * enablings of the END action will be processed); if user-level sees that 1022179193Sjb * this field is non-zero, tracing should be stopped as soon as possible. 1023179193Sjb */ 1024179193Sjbtypedef struct dtrace_status { 1025179193Sjb uint64_t dtst_dyndrops; /* dynamic drops */ 1026179193Sjb uint64_t dtst_dyndrops_rinsing; /* dyn drops due to rinsing */ 1027179193Sjb uint64_t dtst_dyndrops_dirty; /* dyn drops due to dirty */ 1028179193Sjb uint64_t dtst_specdrops; /* speculative drops */ 1029179193Sjb uint64_t dtst_specdrops_busy; /* spec drops due to busy */ 1030179193Sjb uint64_t dtst_specdrops_unavail; /* spec drops due to unavail */ 1031179193Sjb uint64_t dtst_errors; /* total errors */ 1032179193Sjb uint64_t dtst_filled; /* number of filled bufs */ 1033179193Sjb uint64_t dtst_stkstroverflows; /* stack string tab overflows */ 1034179193Sjb uint64_t dtst_dblerrors; /* errors in ERROR probes */ 1035179193Sjb char dtst_killed; /* non-zero if killed */ 1036179193Sjb char dtst_exiting; /* non-zero if exit() called */ 1037179193Sjb char dtst_pad[6]; /* pad out to 64-bit align */ 1038179193Sjb} dtrace_status_t; 1039179193Sjb 1040179193Sjb/* 1041179193Sjb * DTrace Configuration 1042179193Sjb * 1043179193Sjb * User-level may need to understand some elements of the kernel DTrace 1044179193Sjb * configuration in order to generate correct DIF. This information is 1045179193Sjb * conveyed via the dtrace_conf structure. 1046179193Sjb */ 1047179193Sjbtypedef struct dtrace_conf { 1048179193Sjb uint_t dtc_difversion; /* supported DIF version */ 1049179193Sjb uint_t dtc_difintregs; /* # of DIF integer registers */ 1050179193Sjb uint_t dtc_diftupregs; /* # of DIF tuple registers */ 1051179193Sjb uint_t dtc_ctfmodel; /* CTF data model */ 1052179193Sjb uint_t dtc_pad[8]; /* reserved for future use */ 1053179193Sjb} dtrace_conf_t; 1054179193Sjb 1055179193Sjb/* 1056179193Sjb * DTrace Faults 1057179193Sjb * 1058179193Sjb * The constants below DTRACEFLT_LIBRARY indicate probe processing faults; 1059179193Sjb * constants at or above DTRACEFLT_LIBRARY indicate faults in probe 1060179193Sjb * postprocessing at user-level. Probe processing faults induce an ERROR 1061179193Sjb * probe and are replicated in unistd.d to allow users' ERROR probes to decode 1062179193Sjb * the error condition using thse symbolic labels. 1063179193Sjb */ 1064179193Sjb#define DTRACEFLT_UNKNOWN 0 /* Unknown fault */ 1065179193Sjb#define DTRACEFLT_BADADDR 1 /* Bad address */ 1066179193Sjb#define DTRACEFLT_BADALIGN 2 /* Bad alignment */ 1067179193Sjb#define DTRACEFLT_ILLOP 3 /* Illegal operation */ 1068179193Sjb#define DTRACEFLT_DIVZERO 4 /* Divide-by-zero */ 1069179193Sjb#define DTRACEFLT_NOSCRATCH 5 /* Out of scratch space */ 1070179193Sjb#define DTRACEFLT_KPRIV 6 /* Illegal kernel access */ 1071179193Sjb#define DTRACEFLT_UPRIV 7 /* Illegal user access */ 1072179193Sjb#define DTRACEFLT_TUPOFLOW 8 /* Tuple stack overflow */ 1073179193Sjb#define DTRACEFLT_BADSTACK 9 /* Bad stack */ 1074179193Sjb 1075179193Sjb#define DTRACEFLT_LIBRARY 1000 /* Library-level fault */ 1076179193Sjb 1077179193Sjb/* 1078179193Sjb * DTrace Argument Types 1079179193Sjb * 1080179193Sjb * Because it would waste both space and time, argument types do not reside 1081179193Sjb * with the probe. In order to determine argument types for args[X] 1082179193Sjb * variables, the D compiler queries for argument types on a probe-by-probe 1083179193Sjb * basis. (This optimizes for the common case that arguments are either not 1084179193Sjb * used or used in an untyped fashion.) Typed arguments are specified with a 1085179193Sjb * string of the type name in the dtragd_native member of the argument 1086179193Sjb * description structure. Typed arguments may be further translated to types 1087179193Sjb * of greater stability; the provider indicates such a translated argument by 1088179193Sjb * filling in the dtargd_xlate member with the string of the translated type. 1089179193Sjb * Finally, the provider may indicate which argument value a given argument 1090179193Sjb * maps to by setting the dtargd_mapping member -- allowing a single argument 1091179193Sjb * to map to multiple args[X] variables. 1092179193Sjb */ 1093179193Sjbtypedef struct dtrace_argdesc { 1094179193Sjb dtrace_id_t dtargd_id; /* probe identifier */ 1095179193Sjb int dtargd_ndx; /* arg number (-1 iff none) */ 1096179193Sjb int dtargd_mapping; /* value mapping */ 1097179193Sjb char dtargd_native[DTRACE_ARGTYPELEN]; /* native type name */ 1098179193Sjb char dtargd_xlate[DTRACE_ARGTYPELEN]; /* translated type name */ 1099179193Sjb} dtrace_argdesc_t; 1100179193Sjb 1101179193Sjb/* 1102179193Sjb * DTrace Stability Attributes 1103179193Sjb * 1104179193Sjb * Each DTrace provider advertises the name and data stability of each of its 1105179193Sjb * probe description components, as well as its architectural dependencies. 1106179193Sjb * The D compiler can query the provider attributes (dtrace_pattr_t below) in 1107179193Sjb * order to compute the properties of an input program and report them. 1108179193Sjb */ 1109179193Sjbtypedef uint8_t dtrace_stability_t; /* stability code (see attributes(5)) */ 1110179193Sjbtypedef uint8_t dtrace_class_t; /* architectural dependency class */ 1111179193Sjb 1112179193Sjb#define DTRACE_STABILITY_INTERNAL 0 /* private to DTrace itself */ 1113179193Sjb#define DTRACE_STABILITY_PRIVATE 1 /* private to Sun (see docs) */ 1114179193Sjb#define DTRACE_STABILITY_OBSOLETE 2 /* scheduled for removal */ 1115179193Sjb#define DTRACE_STABILITY_EXTERNAL 3 /* not controlled by Sun */ 1116179193Sjb#define DTRACE_STABILITY_UNSTABLE 4 /* new or rapidly changing */ 1117179193Sjb#define DTRACE_STABILITY_EVOLVING 5 /* less rapidly changing */ 1118179193Sjb#define DTRACE_STABILITY_STABLE 6 /* mature interface from Sun */ 1119179193Sjb#define DTRACE_STABILITY_STANDARD 7 /* industry standard */ 1120179193Sjb#define DTRACE_STABILITY_MAX 7 /* maximum valid stability */ 1121179193Sjb 1122179193Sjb#define DTRACE_CLASS_UNKNOWN 0 /* unknown architectural dependency */ 1123179193Sjb#define DTRACE_CLASS_CPU 1 /* CPU-module-specific */ 1124179193Sjb#define DTRACE_CLASS_PLATFORM 2 /* platform-specific (uname -i) */ 1125179193Sjb#define DTRACE_CLASS_GROUP 3 /* hardware-group-specific (uname -m) */ 1126179193Sjb#define DTRACE_CLASS_ISA 4 /* ISA-specific (uname -p) */ 1127179193Sjb#define DTRACE_CLASS_COMMON 5 /* common to all systems */ 1128179193Sjb#define DTRACE_CLASS_MAX 5 /* maximum valid class */ 1129179193Sjb 1130179193Sjb#define DTRACE_PRIV_NONE 0x0000 1131179193Sjb#define DTRACE_PRIV_KERNEL 0x0001 1132179193Sjb#define DTRACE_PRIV_USER 0x0002 1133179193Sjb#define DTRACE_PRIV_PROC 0x0004 1134179193Sjb#define DTRACE_PRIV_OWNER 0x0008 1135179193Sjb#define DTRACE_PRIV_ZONEOWNER 0x0010 1136179193Sjb 1137179193Sjb#define DTRACE_PRIV_ALL \ 1138179193Sjb (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ 1139179193Sjb DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER) 1140179193Sjb 1141179193Sjbtypedef struct dtrace_ppriv { 1142179193Sjb uint32_t dtpp_flags; /* privilege flags */ 1143179193Sjb uid_t dtpp_uid; /* user ID */ 1144179193Sjb zoneid_t dtpp_zoneid; /* zone ID */ 1145179193Sjb} dtrace_ppriv_t; 1146179193Sjb 1147179193Sjbtypedef struct dtrace_attribute { 1148179193Sjb dtrace_stability_t dtat_name; /* entity name stability */ 1149179193Sjb dtrace_stability_t dtat_data; /* entity data stability */ 1150179193Sjb dtrace_class_t dtat_class; /* entity data dependency */ 1151179193Sjb} dtrace_attribute_t; 1152179193Sjb 1153179193Sjbtypedef struct dtrace_pattr { 1154179193Sjb dtrace_attribute_t dtpa_provider; /* provider attributes */ 1155179193Sjb dtrace_attribute_t dtpa_mod; /* module attributes */ 1156179193Sjb dtrace_attribute_t dtpa_func; /* function attributes */ 1157179193Sjb dtrace_attribute_t dtpa_name; /* name attributes */ 1158179193Sjb dtrace_attribute_t dtpa_args; /* args[] attributes */ 1159179193Sjb} dtrace_pattr_t; 1160179193Sjb 1161179193Sjbtypedef struct dtrace_providerdesc { 1162179193Sjb char dtvd_name[DTRACE_PROVNAMELEN]; /* provider name */ 1163179193Sjb dtrace_pattr_t dtvd_attr; /* stability attributes */ 1164179193Sjb dtrace_ppriv_t dtvd_priv; /* privileges required */ 1165179193Sjb} dtrace_providerdesc_t; 1166179193Sjb 1167179193Sjb/* 1168179193Sjb * DTrace Pseudodevice Interface 1169179193Sjb * 1170179193Sjb * DTrace is controlled through ioctl(2)'s to the in-kernel dtrace:dtrace 1171179193Sjb * pseudodevice driver. These ioctls comprise the user-kernel interface to 1172179193Sjb * DTrace. 1173179193Sjb */ 1174179193Sjb#define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) 1175179193Sjb#define DTRACEIOC_PROVIDER (DTRACEIOC | 1) /* provider query */ 1176179193Sjb#define DTRACEIOC_PROBES (DTRACEIOC | 2) /* probe query */ 1177179193Sjb#define DTRACEIOC_BUFSNAP (DTRACEIOC | 4) /* snapshot buffer */ 1178179193Sjb#define DTRACEIOC_PROBEMATCH (DTRACEIOC | 5) /* match probes */ 1179179193Sjb#define DTRACEIOC_ENABLE (DTRACEIOC | 6) /* enable probes */ 1180179193Sjb#define DTRACEIOC_AGGSNAP (DTRACEIOC | 7) /* snapshot agg. */ 1181179193Sjb#define DTRACEIOC_EPROBE (DTRACEIOC | 8) /* get eprobe desc. */ 1182179193Sjb#define DTRACEIOC_PROBEARG (DTRACEIOC | 9) /* get probe arg */ 1183179193Sjb#define DTRACEIOC_CONF (DTRACEIOC | 10) /* get config. */ 1184179193Sjb#define DTRACEIOC_STATUS (DTRACEIOC | 11) /* get status */ 1185179193Sjb#define DTRACEIOC_GO (DTRACEIOC | 12) /* start tracing */ 1186179193Sjb#define DTRACEIOC_STOP (DTRACEIOC | 13) /* stop tracing */ 1187179193Sjb#define DTRACEIOC_AGGDESC (DTRACEIOC | 15) /* get agg. desc. */ 1188179193Sjb#define DTRACEIOC_FORMAT (DTRACEIOC | 16) /* get format str */ 1189179193Sjb#define DTRACEIOC_DOFGET (DTRACEIOC | 17) /* get DOF */ 1190179193Sjb#define DTRACEIOC_REPLICATE (DTRACEIOC | 18) /* replicate enab */ 1191179193Sjb 1192179193Sjb/* 1193179193Sjb * DTrace Helpers 1194179193Sjb * 1195179193Sjb * In general, DTrace establishes probes in processes and takes actions on 1196179193Sjb * processes without knowing their specific user-level structures. Instead of 1197179193Sjb * existing in the framework, process-specific knowledge is contained by the 1198179193Sjb * enabling D program -- which can apply process-specific knowledge by making 1199179193Sjb * appropriate use of DTrace primitives like copyin() and copyinstr() to 1200179193Sjb * operate on user-level data. However, there may exist some specific probes 1201179193Sjb * of particular semantic relevance that the application developer may wish to 1202179193Sjb * explicitly export. For example, an application may wish to export a probe 1203179193Sjb * at the point that it begins and ends certain well-defined transactions. In 1204179193Sjb * addition to providing probes, programs may wish to offer assistance for 1205179193Sjb * certain actions. For example, in highly dynamic environments (e.g., Java), 1206179193Sjb * it may be difficult to obtain a stack trace in terms of meaningful symbol 1207179193Sjb * names (the translation from instruction addresses to corresponding symbol 1208179193Sjb * names may only be possible in situ); these environments may wish to define 1209179193Sjb * a series of actions to be applied in situ to obtain a meaningful stack 1210179193Sjb * trace. 1211179193Sjb * 1212179193Sjb * These two mechanisms -- user-level statically defined tracing and assisting 1213179193Sjb * DTrace actions -- are provided via DTrace _helpers_. Helpers are specified 1214179193Sjb * via DOF, but unlike enabling DOF, helper DOF may contain definitions of 1215179193Sjb * providers, probes and their arguments. If a helper wishes to provide 1216179193Sjb * action assistance, probe descriptions and corresponding DIF actions may be 1217179193Sjb * specified in the helper DOF. For such helper actions, however, the probe 1218179193Sjb * description describes the specific helper: all DTrace helpers have the 1219179193Sjb * provider name "dtrace" and the module name "helper", and the name of the 1220179193Sjb * helper is contained in the function name (for example, the ustack() helper 1221179193Sjb * is named "ustack"). Any helper-specific name may be contained in the name 1222179193Sjb * (for example, if a helper were to have a constructor, it might be named 1223179193Sjb * "dtrace:helper:<helper>:init"). Helper actions are only called when the 1224179193Sjb * action that they are helping is taken. Helper actions may only return DIF 1225179193Sjb * expressions, and may only call the following subroutines: 1226179193Sjb * 1227179193Sjb * alloca() <= Allocates memory out of the consumer's scratch space 1228179193Sjb * bcopy() <= Copies memory to scratch space 1229179193Sjb * copyin() <= Copies memory from user-level into consumer's scratch 1230179193Sjb * copyinto() <= Copies memory into a specific location in scratch 1231179193Sjb * copyinstr() <= Copies a string into a specific location in scratch 1232179193Sjb * 1233179193Sjb * Helper actions may only access the following built-in variables: 1234179193Sjb * 1235179193Sjb * curthread <= Current kthread_t pointer 1236179193Sjb * tid <= Current thread identifier 1237179193Sjb * pid <= Current process identifier 1238179193Sjb * ppid <= Parent process identifier 1239179193Sjb * uid <= Current user ID 1240179193Sjb * gid <= Current group ID 1241179193Sjb * execname <= Current executable name 1242179193Sjb * zonename <= Current zone name 1243179193Sjb * 1244179193Sjb * Helper actions may not manipulate or allocate dynamic variables, but they 1245179193Sjb * may have clause-local and statically-allocated global variables. The 1246179193Sjb * helper action variable state is specific to the helper action -- variables 1247179193Sjb * used by the helper action may not be accessed outside of the helper 1248179193Sjb * action, and the helper action may not access variables that like outside 1249179193Sjb * of it. Helper actions may not load from kernel memory at-large; they are 1250179193Sjb * restricting to loading current user state (via copyin() and variants) and 1251179193Sjb * scratch space. As with probe enablings, helper actions are executed in 1252179193Sjb * program order. The result of the helper action is the result of the last 1253179193Sjb * executing helper expression. 1254179193Sjb * 1255179193Sjb * Helpers -- composed of either providers/probes or probes/actions (or both) 1256179193Sjb * -- are added by opening the "helper" minor node, and issuing an ioctl(2) 1257179193Sjb * (DTRACEHIOC_ADDDOF) that specifies the dof_helper_t structure. This 1258179193Sjb * encapsulates the name and base address of the user-level library or 1259179193Sjb * executable publishing the helpers and probes as well as the DOF that 1260179193Sjb * contains the definitions of those helpers and probes. 1261179193Sjb * 1262179193Sjb * The DTRACEHIOC_ADD and DTRACEHIOC_REMOVE are left in place for legacy 1263179193Sjb * helpers and should no longer be used. No other ioctls are valid on the 1264179193Sjb * helper minor node. 1265179193Sjb */ 1266179193Sjb#define DTRACEHIOC (('d' << 24) | ('t' << 16) | ('h' << 8)) 1267179193Sjb#define DTRACEHIOC_ADD (DTRACEHIOC | 1) /* add helper */ 1268179193Sjb#define DTRACEHIOC_REMOVE (DTRACEHIOC | 2) /* remove helper */ 1269179193Sjb#define DTRACEHIOC_ADDDOF (DTRACEHIOC | 3) /* add helper DOF */ 1270179193Sjb 1271179193Sjbtypedef struct dof_helper { 1272179193Sjb char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ 1273179193Sjb uint64_t dofhp_addr; /* base address of object */ 1274179193Sjb uint64_t dofhp_dof; /* address of helper DOF */ 1275179193Sjb} dof_helper_t; 1276179193Sjb 1277179193Sjb#define DTRACEMNR_DTRACE "dtrace" /* node for DTrace ops */ 1278179193Sjb#define DTRACEMNR_HELPER "helper" /* node for helpers */ 1279179193Sjb#define DTRACEMNRN_DTRACE 0 /* minor for DTrace ops */ 1280179193Sjb#define DTRACEMNRN_HELPER 1 /* minor for helpers */ 1281179193Sjb#define DTRACEMNRN_CLONE 2 /* first clone minor */ 1282179193Sjb 1283179193Sjb#ifdef _KERNEL 1284179193Sjb 1285179193Sjb/* 1286179193Sjb * DTrace Provider API 1287179193Sjb * 1288179193Sjb * The following functions are implemented by the DTrace framework and are 1289179193Sjb * used to implement separate in-kernel DTrace providers. Common functions 1290179193Sjb * are provided in uts/common/os/dtrace.c. ISA-dependent subroutines are 1291179193Sjb * defined in uts/<isa>/dtrace/dtrace_asm.s or uts/<isa>/dtrace/dtrace_isa.c. 1292179193Sjb * 1293179193Sjb * The provider API has two halves: the API that the providers consume from 1294179193Sjb * DTrace, and the API that providers make available to DTrace. 1295179193Sjb * 1296179193Sjb * 1 Framework-to-Provider API 1297179193Sjb * 1298179193Sjb * 1.1 Overview 1299179193Sjb * 1300179193Sjb * The Framework-to-Provider API is represented by the dtrace_pops structure 1301179193Sjb * that the provider passes to the framework when registering itself. This 1302179193Sjb * structure consists of the following members: 1303179193Sjb * 1304179193Sjb * dtps_provide() <-- Provide all probes, all modules 1305179193Sjb * dtps_provide_module() <-- Provide all probes in specified module 1306179193Sjb * dtps_enable() <-- Enable specified probe 1307179193Sjb * dtps_disable() <-- Disable specified probe 1308179193Sjb * dtps_suspend() <-- Suspend specified probe 1309179193Sjb * dtps_resume() <-- Resume specified probe 1310179193Sjb * dtps_getargdesc() <-- Get the argument description for args[X] 1311179193Sjb * dtps_getargval() <-- Get the value for an argX or args[X] variable 1312179193Sjb * dtps_usermode() <-- Find out if the probe was fired in user mode 1313179193Sjb * dtps_destroy() <-- Destroy all state associated with this probe 1314179193Sjb * 1315179193Sjb * 1.2 void dtps_provide(void *arg, const dtrace_probedesc_t *spec) 1316179193Sjb * 1317179193Sjb * 1.2.1 Overview 1318179193Sjb * 1319179193Sjb * Called to indicate that the provider should provide all probes. If the 1320179193Sjb * specified description is non-NULL, dtps_provide() is being called because 1321179193Sjb * no probe matched a specified probe -- if the provider has the ability to 1322179193Sjb * create custom probes, it may wish to create a probe that matches the 1323179193Sjb * specified description. 1324179193Sjb * 1325179193Sjb * 1.2.2 Arguments and notes 1326179193Sjb * 1327179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1328179193Sjb * second argument is a pointer to a probe description that the provider may 1329179193Sjb * wish to consider when creating custom probes. The provider is expected to 1330179193Sjb * call back into the DTrace framework via dtrace_probe_create() to create 1331179193Sjb * any necessary probes. dtps_provide() may be called even if the provider 1332179193Sjb * has made available all probes; the provider should check the return value 1333179193Sjb * of dtrace_probe_create() to handle this case. Note that the provider need 1334179193Sjb * not implement both dtps_provide() and dtps_provide_module(); see 1335179193Sjb * "Arguments and Notes" for dtrace_register(), below. 1336179193Sjb * 1337179193Sjb * 1.2.3 Return value 1338179193Sjb * 1339179193Sjb * None. 1340179193Sjb * 1341179193Sjb * 1.2.4 Caller's context 1342179193Sjb * 1343179193Sjb * dtps_provide() is typically called from open() or ioctl() context, but may 1344179193Sjb * be called from other contexts as well. The DTrace framework is locked in 1345179193Sjb * such a way that providers may not register or unregister. This means that 1346179193Sjb * the provider may not call any DTrace API that affects its registration with 1347179193Sjb * the framework, including dtrace_register(), dtrace_unregister(), 1348179193Sjb * dtrace_invalidate(), and dtrace_condense(). However, the context is such 1349179193Sjb * that the provider may (and indeed, is expected to) call probe-related 1350179193Sjb * DTrace routines, including dtrace_probe_create(), dtrace_probe_lookup(), 1351179193Sjb * and dtrace_probe_arg(). 1352179193Sjb * 1353179193Sjb * 1.3 void dtps_provide_module(void *arg, struct modctl *mp) 1354179193Sjb * 1355179193Sjb * 1.3.1 Overview 1356179193Sjb * 1357179193Sjb * Called to indicate that the provider should provide all probes in the 1358179193Sjb * specified module. 1359179193Sjb * 1360179193Sjb * 1.3.2 Arguments and notes 1361179193Sjb * 1362179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1363179193Sjb * second argument is a pointer to a modctl structure that indicates the 1364179193Sjb * module for which probes should be created. 1365179193Sjb * 1366179193Sjb * 1.3.3 Return value 1367179193Sjb * 1368179193Sjb * None. 1369179193Sjb * 1370179193Sjb * 1.3.4 Caller's context 1371179193Sjb * 1372179193Sjb * dtps_provide_module() may be called from open() or ioctl() context, but 1373179193Sjb * may also be called from a module loading context. mod_lock is held, and 1374179193Sjb * the DTrace framework is locked in such a way that providers may not 1375179193Sjb * register or unregister. This means that the provider may not call any 1376179193Sjb * DTrace API that affects its registration with the framework, including 1377179193Sjb * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 1378179193Sjb * dtrace_condense(). However, the context is such that the provider may (and 1379179193Sjb * indeed, is expected to) call probe-related DTrace routines, including 1380179193Sjb * dtrace_probe_create(), dtrace_probe_lookup(), and dtrace_probe_arg(). Note 1381179193Sjb * that the provider need not implement both dtps_provide() and 1382179193Sjb * dtps_provide_module(); see "Arguments and Notes" for dtrace_register(), 1383179193Sjb * below. 1384179193Sjb * 1385179193Sjb * 1.4 void dtps_enable(void *arg, dtrace_id_t id, void *parg) 1386179193Sjb * 1387179193Sjb * 1.4.1 Overview 1388179193Sjb * 1389179193Sjb * Called to enable the specified probe. 1390179193Sjb * 1391179193Sjb * 1.4.2 Arguments and notes 1392179193Sjb * 1393179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1394179193Sjb * second argument is the identifier of the probe to be enabled. The third 1395179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). 1396179193Sjb * dtps_enable() will be called when a probe transitions from not being 1397179193Sjb * enabled at all to having one or more ECB. The number of ECBs associated 1398179193Sjb * with the probe may change without subsequent calls into the provider. 1399179193Sjb * When the number of ECBs drops to zero, the provider will be explicitly 1400179193Sjb * told to disable the probe via dtps_disable(). dtrace_probe() should never 1401179193Sjb * be called for a probe identifier that hasn't been explicitly enabled via 1402179193Sjb * dtps_enable(). 1403179193Sjb * 1404179193Sjb * 1.4.3 Return value 1405179193Sjb * 1406179193Sjb * None. 1407179193Sjb * 1408179193Sjb * 1.4.4 Caller's context 1409179193Sjb * 1410179193Sjb * The DTrace framework is locked in such a way that it may not be called 1411179193Sjb * back into at all. cpu_lock is held. mod_lock is not held and may not 1412179193Sjb * be acquired. 1413179193Sjb * 1414179193Sjb * 1.5 void dtps_disable(void *arg, dtrace_id_t id, void *parg) 1415179193Sjb * 1416179193Sjb * 1.5.1 Overview 1417179193Sjb * 1418179193Sjb * Called to disable the specified probe. 1419179193Sjb * 1420179193Sjb * 1.5.2 Arguments and notes 1421179193Sjb * 1422179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1423179193Sjb * second argument is the identifier of the probe to be disabled. The third 1424179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). 1425179193Sjb * dtps_disable() will be called when a probe transitions from being enabled 1426179193Sjb * to having zero ECBs. dtrace_probe() should never be called for a probe 1427179193Sjb * identifier that has been explicitly enabled via dtps_disable(). 1428179193Sjb * 1429179193Sjb * 1.5.3 Return value 1430179193Sjb * 1431179193Sjb * None. 1432179193Sjb * 1433179193Sjb * 1.5.4 Caller's context 1434179193Sjb * 1435179193Sjb * The DTrace framework is locked in such a way that it may not be called 1436179193Sjb * back into at all. cpu_lock is held. mod_lock is not held and may not 1437179193Sjb * be acquired. 1438179193Sjb * 1439179193Sjb * 1.6 void dtps_suspend(void *arg, dtrace_id_t id, void *parg) 1440179193Sjb * 1441179193Sjb * 1.6.1 Overview 1442179193Sjb * 1443179193Sjb * Called to suspend the specified enabled probe. This entry point is for 1444179193Sjb * providers that may need to suspend some or all of their probes when CPUs 1445179193Sjb * are being powered on or when the boot monitor is being entered for a 1446179193Sjb * prolonged period of time. 1447179193Sjb * 1448179193Sjb * 1.6.2 Arguments and notes 1449179193Sjb * 1450179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1451179193Sjb * second argument is the identifier of the probe to be suspended. The 1452179193Sjb * third argument is the probe argument as passed to dtrace_probe_create(). 1453179193Sjb * dtps_suspend will only be called on an enabled probe. Providers that 1454179193Sjb * provide a dtps_suspend entry point will want to take roughly the action 1455179193Sjb * that it takes for dtps_disable. 1456179193Sjb * 1457179193Sjb * 1.6.3 Return value 1458179193Sjb * 1459179193Sjb * None. 1460179193Sjb * 1461179193Sjb * 1.6.4 Caller's context 1462179193Sjb * 1463179193Sjb * Interrupts are disabled. The DTrace framework is in a state such that the 1464179193Sjb * specified probe cannot be disabled or destroyed for the duration of 1465179193Sjb * dtps_suspend(). As interrupts are disabled, the provider is afforded 1466179193Sjb * little latitude; the provider is expected to do no more than a store to 1467179193Sjb * memory. 1468179193Sjb * 1469179193Sjb * 1.7 void dtps_resume(void *arg, dtrace_id_t id, void *parg) 1470179193Sjb * 1471179193Sjb * 1.7.1 Overview 1472179193Sjb * 1473179193Sjb * Called to resume the specified enabled probe. This entry point is for 1474179193Sjb * providers that may need to resume some or all of their probes after the 1475179193Sjb * completion of an event that induced a call to dtps_suspend(). 1476179193Sjb * 1477179193Sjb * 1.7.2 Arguments and notes 1478179193Sjb * 1479179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1480179193Sjb * second argument is the identifier of the probe to be resumed. The 1481179193Sjb * third argument is the probe argument as passed to dtrace_probe_create(). 1482179193Sjb * dtps_resume will only be called on an enabled probe. Providers that 1483179193Sjb * provide a dtps_resume entry point will want to take roughly the action 1484179193Sjb * that it takes for dtps_enable. 1485179193Sjb * 1486179193Sjb * 1.7.3 Return value 1487179193Sjb * 1488179193Sjb * None. 1489179193Sjb * 1490179193Sjb * 1.7.4 Caller's context 1491179193Sjb * 1492179193Sjb * Interrupts are disabled. The DTrace framework is in a state such that the 1493179193Sjb * specified probe cannot be disabled or destroyed for the duration of 1494179193Sjb * dtps_resume(). As interrupts are disabled, the provider is afforded 1495179193Sjb * little latitude; the provider is expected to do no more than a store to 1496179193Sjb * memory. 1497179193Sjb * 1498179193Sjb * 1.8 void dtps_getargdesc(void *arg, dtrace_id_t id, void *parg, 1499179193Sjb * dtrace_argdesc_t *desc) 1500179193Sjb * 1501179193Sjb * 1.8.1 Overview 1502179193Sjb * 1503179193Sjb * Called to retrieve the argument description for an args[X] variable. 1504179193Sjb * 1505179193Sjb * 1.8.2 Arguments and notes 1506179193Sjb * 1507179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1508179193Sjb * second argument is the identifier of the current probe. The third 1509179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). The 1510179193Sjb * fourth argument is a pointer to the argument description. This 1511179193Sjb * description is both an input and output parameter: it contains the 1512179193Sjb * index of the desired argument in the dtargd_ndx field, and expects 1513179193Sjb * the other fields to be filled in upon return. If there is no argument 1514179193Sjb * corresponding to the specified index, the dtargd_ndx field should be set 1515179193Sjb * to DTRACE_ARGNONE. 1516179193Sjb * 1517179193Sjb * 1.8.3 Return value 1518179193Sjb * 1519179193Sjb * None. The dtargd_ndx, dtargd_native, dtargd_xlate and dtargd_mapping 1520179193Sjb * members of the dtrace_argdesc_t structure are all output values. 1521179193Sjb * 1522179193Sjb * 1.8.4 Caller's context 1523179193Sjb * 1524179193Sjb * dtps_getargdesc() is called from ioctl() context. mod_lock is held, and 1525179193Sjb * the DTrace framework is locked in such a way that providers may not 1526179193Sjb * register or unregister. This means that the provider may not call any 1527179193Sjb * DTrace API that affects its registration with the framework, including 1528179193Sjb * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 1529179193Sjb * dtrace_condense(). 1530179193Sjb * 1531179193Sjb * 1.9 uint64_t dtps_getargval(void *arg, dtrace_id_t id, void *parg, 1532179193Sjb * int argno, int aframes) 1533179193Sjb * 1534179193Sjb * 1.9.1 Overview 1535179193Sjb * 1536179193Sjb * Called to retrieve a value for an argX or args[X] variable. 1537179193Sjb * 1538179193Sjb * 1.9.2 Arguments and notes 1539179193Sjb * 1540179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1541179193Sjb * second argument is the identifier of the current probe. The third 1542179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). The 1543179193Sjb * fourth argument is the number of the argument (the X in the example in 1544179193Sjb * 1.9.1). The fifth argument is the number of stack frames that were used 1545179193Sjb * to get from the actual place in the code that fired the probe to 1546179193Sjb * dtrace_probe() itself, the so-called artificial frames. This argument may 1547179193Sjb * be used to descend an appropriate number of frames to find the correct 1548179193Sjb * values. If this entry point is left NULL, the dtrace_getarg() built-in 1549179193Sjb * function is used. 1550179193Sjb * 1551179193Sjb * 1.9.3 Return value 1552179193Sjb * 1553179193Sjb * The value of the argument. 1554179193Sjb * 1555179193Sjb * 1.9.4 Caller's context 1556179193Sjb * 1557179193Sjb * This is called from within dtrace_probe() meaning that interrupts 1558179193Sjb * are disabled. No locks should be taken within this entry point. 1559179193Sjb * 1560179193Sjb * 1.10 int dtps_usermode(void *arg, dtrace_id_t id, void *parg) 1561179193Sjb * 1562179193Sjb * 1.10.1 Overview 1563179193Sjb * 1564179193Sjb * Called to determine if the probe was fired in a user context. 1565179193Sjb * 1566179193Sjb * 1.10.2 Arguments and notes 1567179193Sjb * 1568179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1569179193Sjb * second argument is the identifier of the current probe. The third 1570179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). This 1571179193Sjb * entry point must not be left NULL for providers whose probes allow for 1572179193Sjb * mixed mode tracing, that is to say those probes that can fire during 1573179193Sjb * kernel- _or_ user-mode execution 1574179193Sjb * 1575179193Sjb * 1.10.3 Return value 1576179193Sjb * 1577179193Sjb * A boolean value. 1578179193Sjb * 1579179193Sjb * 1.10.4 Caller's context 1580179193Sjb * 1581179193Sjb * This is called from within dtrace_probe() meaning that interrupts 1582179193Sjb * are disabled. No locks should be taken within this entry point. 1583179193Sjb * 1584179193Sjb * 1.11 void dtps_destroy(void *arg, dtrace_id_t id, void *parg) 1585179193Sjb * 1586179193Sjb * 1.11.1 Overview 1587179193Sjb * 1588179193Sjb * Called to destroy the specified probe. 1589179193Sjb * 1590179193Sjb * 1.11.2 Arguments and notes 1591179193Sjb * 1592179193Sjb * The first argument is the cookie as passed to dtrace_register(). The 1593179193Sjb * second argument is the identifier of the probe to be destroyed. The third 1594179193Sjb * argument is the probe argument as passed to dtrace_probe_create(). The 1595179193Sjb * provider should free all state associated with the probe. The framework 1596179193Sjb * guarantees that dtps_destroy() is only called for probes that have either 1597179193Sjb * been disabled via dtps_disable() or were never enabled via dtps_enable(). 1598179193Sjb * Once dtps_disable() has been called for a probe, no further call will be 1599179193Sjb * made specifying the probe. 1600179193Sjb * 1601179193Sjb * 1.11.3 Return value 1602179193Sjb * 1603179193Sjb * None. 1604179193Sjb * 1605179193Sjb * 1.11.4 Caller's context 1606179193Sjb * 1607179193Sjb * The DTrace framework is locked in such a way that it may not be called 1608179193Sjb * back into at all. mod_lock is held. cpu_lock is not held, and may not be 1609179193Sjb * acquired. 1610179193Sjb * 1611179193Sjb * 1612179193Sjb * 2 Provider-to-Framework API 1613179193Sjb * 1614179193Sjb * 2.1 Overview 1615179193Sjb * 1616179193Sjb * The Provider-to-Framework API provides the mechanism for the provider to 1617179193Sjb * register itself with the DTrace framework, to create probes, to lookup 1618179193Sjb * probes and (most importantly) to fire probes. The Provider-to-Framework 1619179193Sjb * consists of: 1620179193Sjb * 1621179193Sjb * dtrace_register() <-- Register a provider with the DTrace framework 1622179193Sjb * dtrace_unregister() <-- Remove a provider's DTrace registration 1623179193Sjb * dtrace_invalidate() <-- Invalidate the specified provider 1624179193Sjb * dtrace_condense() <-- Remove a provider's unenabled probes 1625179193Sjb * dtrace_attached() <-- Indicates whether or not DTrace has attached 1626179193Sjb * dtrace_probe_create() <-- Create a DTrace probe 1627179193Sjb * dtrace_probe_lookup() <-- Lookup a DTrace probe based on its name 1628179193Sjb * dtrace_probe_arg() <-- Return the probe argument for a specific probe 1629179193Sjb * dtrace_probe() <-- Fire the specified probe 1630179193Sjb * 1631179193Sjb * 2.2 int dtrace_register(const char *name, const dtrace_pattr_t *pap, 1632179193Sjb * uint32_t priv, cred_t *cr, const dtrace_pops_t *pops, void *arg, 1633179193Sjb * dtrace_provider_id_t *idp) 1634179193Sjb * 1635179193Sjb * 2.2.1 Overview 1636179193Sjb * 1637179193Sjb * dtrace_register() registers the calling provider with the DTrace 1638179193Sjb * framework. It should generally be called by DTrace providers in their 1639179193Sjb * attach(9E) entry point. 1640179193Sjb * 1641179193Sjb * 2.2.2 Arguments and Notes 1642179193Sjb * 1643179193Sjb * The first argument is the name of the provider. The second argument is a 1644179193Sjb * pointer to the stability attributes for the provider. The third argument 1645179193Sjb * is the privilege flags for the provider, and must be some combination of: 1646179193Sjb * 1647179193Sjb * DTRACE_PRIV_NONE <= All users may enable probes from this provider 1648179193Sjb * 1649179193Sjb * DTRACE_PRIV_PROC <= Any user with privilege of PRIV_DTRACE_PROC may 1650179193Sjb * enable probes from this provider 1651179193Sjb * 1652179193Sjb * DTRACE_PRIV_USER <= Any user with privilege of PRIV_DTRACE_USER may 1653179193Sjb * enable probes from this provider 1654179193Sjb * 1655179193Sjb * DTRACE_PRIV_KERNEL <= Any user with privilege of PRIV_DTRACE_KERNEL 1656179193Sjb * may enable probes from this provider 1657179193Sjb * 1658179193Sjb * DTRACE_PRIV_OWNER <= This flag places an additional constraint on 1659179193Sjb * the privilege requirements above. These probes 1660179193Sjb * require either (a) a user ID matching the user 1661179193Sjb * ID of the cred passed in the fourth argument 1662179193Sjb * or (b) the PRIV_PROC_OWNER privilege. 1663179193Sjb * 1664179193Sjb * DTRACE_PRIV_ZONEOWNER<= This flag places an additional constraint on 1665179193Sjb * the privilege requirements above. These probes 1666179193Sjb * require either (a) a zone ID matching the zone 1667179193Sjb * ID of the cred passed in the fourth argument 1668179193Sjb * or (b) the PRIV_PROC_ZONE privilege. 1669179193Sjb * 1670179193Sjb * Note that these flags designate the _visibility_ of the probes, not 1671179193Sjb * the conditions under which they may or may not fire. 1672179193Sjb * 1673179193Sjb * The fourth argument is the credential that is associated with the 1674179193Sjb * provider. This argument should be NULL if the privilege flags don't 1675179193Sjb * include DTRACE_PRIV_OWNER or DTRACE_PRIV_ZONEOWNER. If non-NULL, the 1676179193Sjb * framework stashes the uid and zoneid represented by this credential 1677179193Sjb * for use at probe-time, in implicit predicates. These limit visibility 1678179193Sjb * of the probes to users and/or zones which have sufficient privilege to 1679179193Sjb * access them. 1680179193Sjb * 1681179193Sjb * The fifth argument is a DTrace provider operations vector, which provides 1682179193Sjb * the implementation for the Framework-to-Provider API. (See Section 1, 1683179193Sjb * above.) This must be non-NULL, and each member must be non-NULL. The 1684179193Sjb * exceptions to this are (1) the dtps_provide() and dtps_provide_module() 1685179193Sjb * members (if the provider so desires, _one_ of these members may be left 1686179193Sjb * NULL -- denoting that the provider only implements the other) and (2) 1687179193Sjb * the dtps_suspend() and dtps_resume() members, which must either both be 1688179193Sjb * NULL or both be non-NULL. 1689179193Sjb * 1690179193Sjb * The sixth argument is a cookie to be specified as the first argument for 1691179193Sjb * each function in the Framework-to-Provider API. This argument may have 1692179193Sjb * any value. 1693179193Sjb * 1694179193Sjb * The final argument is a pointer to dtrace_provider_id_t. If 1695179193Sjb * dtrace_register() successfully completes, the provider identifier will be 1696179193Sjb * stored in the memory pointed to be this argument. This argument must be 1697179193Sjb * non-NULL. 1698179193Sjb * 1699179193Sjb * 2.2.3 Return value 1700179193Sjb * 1701179193Sjb * On success, dtrace_register() returns 0 and stores the new provider's 1702179193Sjb * identifier into the memory pointed to by the idp argument. On failure, 1703179193Sjb * dtrace_register() returns an errno: 1704179193Sjb * 1705179193Sjb * EINVAL The arguments passed to dtrace_register() were somehow invalid. 1706179193Sjb * This may because a parameter that must be non-NULL was NULL, 1707179193Sjb * because the name was invalid (either empty or an illegal 1708179193Sjb * provider name) or because the attributes were invalid. 1709179193Sjb * 1710179193Sjb * No other failure code is returned. 1711179193Sjb * 1712179193Sjb * 2.2.4 Caller's context 1713179193Sjb * 1714179193Sjb * dtrace_register() may induce calls to dtrace_provide(); the provider must 1715179193Sjb * hold no locks across dtrace_register() that may also be acquired by 1716179193Sjb * dtrace_provide(). cpu_lock and mod_lock must not be held. 1717179193Sjb * 1718179193Sjb * 2.3 int dtrace_unregister(dtrace_provider_t id) 1719179193Sjb * 1720179193Sjb * 2.3.1 Overview 1721179193Sjb * 1722179193Sjb * Unregisters the specified provider from the DTrace framework. It should 1723179193Sjb * generally be called by DTrace providers in their detach(9E) entry point. 1724179193Sjb * 1725179193Sjb * 2.3.2 Arguments and Notes 1726179193Sjb * 1727179193Sjb * The only argument is the provider identifier, as returned from a 1728179193Sjb * successful call to dtrace_register(). As a result of calling 1729179193Sjb * dtrace_unregister(), the DTrace framework will call back into the provider 1730179193Sjb * via the dtps_destroy() entry point. Once dtrace_unregister() successfully 1731179193Sjb * completes, however, the DTrace framework will no longer make calls through 1732179193Sjb * the Framework-to-Provider API. 1733179193Sjb * 1734179193Sjb * 2.3.3 Return value 1735179193Sjb * 1736179193Sjb * On success, dtrace_unregister returns 0. On failure, dtrace_unregister() 1737179193Sjb * returns an errno: 1738179193Sjb * 1739179193Sjb * EBUSY There are currently processes that have the DTrace pseudodevice 1740179193Sjb * open, or there exists an anonymous enabling that hasn't yet 1741179193Sjb * been claimed. 1742179193Sjb * 1743179193Sjb * No other failure code is returned. 1744179193Sjb * 1745179193Sjb * 2.3.4 Caller's context 1746179193Sjb * 1747179193Sjb * Because a call to dtrace_unregister() may induce calls through the 1748179193Sjb * Framework-to-Provider API, the caller may not hold any lock across 1749179193Sjb * dtrace_register() that is also acquired in any of the Framework-to- 1750179193Sjb * Provider API functions. Additionally, mod_lock may not be held. 1751179193Sjb * 1752179193Sjb * 2.4 void dtrace_invalidate(dtrace_provider_id_t id) 1753179193Sjb * 1754179193Sjb * 2.4.1 Overview 1755179193Sjb * 1756179193Sjb * Invalidates the specified provider. All subsequent probe lookups for the 1757179193Sjb * specified provider will fail, but its probes will not be removed. 1758179193Sjb * 1759179193Sjb * 2.4.2 Arguments and note 1760179193Sjb * 1761179193Sjb * The only argument is the provider identifier, as returned from a 1762179193Sjb * successful call to dtrace_register(). In general, a provider's probes 1763179193Sjb * always remain valid; dtrace_invalidate() is a mechanism for invalidating 1764179193Sjb * an entire provider, regardless of whether or not probes are enabled or 1765179193Sjb * not. Note that dtrace_invalidate() will _not_ prevent already enabled 1766179193Sjb * probes from firing -- it will merely prevent any new enablings of the 1767179193Sjb * provider's probes. 1768179193Sjb * 1769179193Sjb * 2.5 int dtrace_condense(dtrace_provider_id_t id) 1770179193Sjb * 1771179193Sjb * 2.5.1 Overview 1772179193Sjb * 1773179193Sjb * Removes all the unenabled probes for the given provider. This function is 1774179193Sjb * not unlike dtrace_unregister(), except that it doesn't remove the 1775179193Sjb * provider just as many of its associated probes as it can. 1776179193Sjb * 1777179193Sjb * 2.5.2 Arguments and Notes 1778179193Sjb * 1779179193Sjb * As with dtrace_unregister(), the sole argument is the provider identifier 1780179193Sjb * as returned from a successful call to dtrace_register(). As a result of 1781179193Sjb * calling dtrace_condense(), the DTrace framework will call back into the 1782179193Sjb * given provider's dtps_destroy() entry point for each of the provider's 1783179193Sjb * unenabled probes. 1784179193Sjb * 1785179193Sjb * 2.5.3 Return value 1786179193Sjb * 1787179193Sjb * Currently, dtrace_condense() always returns 0. However, consumers of this 1788179193Sjb * function should check the return value as appropriate; its behavior may 1789179193Sjb * change in the future. 1790179193Sjb * 1791179193Sjb * 2.5.4 Caller's context 1792179193Sjb * 1793179193Sjb * As with dtrace_unregister(), the caller may not hold any lock across 1794179193Sjb * dtrace_condense() that is also acquired in the provider's entry points. 1795179193Sjb * Also, mod_lock may not be held. 1796179193Sjb * 1797179193Sjb * 2.6 int dtrace_attached() 1798179193Sjb * 1799179193Sjb * 2.6.1 Overview 1800179193Sjb * 1801179193Sjb * Indicates whether or not DTrace has attached. 1802179193Sjb * 1803179193Sjb * 2.6.2 Arguments and Notes 1804179193Sjb * 1805179193Sjb * For most providers, DTrace makes initial contact beyond registration. 1806179193Sjb * That is, once a provider has registered with DTrace, it waits to hear 1807179193Sjb * from DTrace to create probes. However, some providers may wish to 1808179193Sjb * proactively create probes without first being told by DTrace to do so. 1809179193Sjb * If providers wish to do this, they must first call dtrace_attached() to 1810179193Sjb * determine if DTrace itself has attached. If dtrace_attached() returns 0, 1811179193Sjb * the provider must not make any other Provider-to-Framework API call. 1812179193Sjb * 1813179193Sjb * 2.6.3 Return value 1814179193Sjb * 1815179193Sjb * dtrace_attached() returns 1 if DTrace has attached, 0 otherwise. 1816179193Sjb * 1817179193Sjb * 2.7 int dtrace_probe_create(dtrace_provider_t id, const char *mod, 1818179193Sjb * const char *func, const char *name, int aframes, void *arg) 1819179193Sjb * 1820179193Sjb * 2.7.1 Overview 1821179193Sjb * 1822179193Sjb * Creates a probe with specified module name, function name, and name. 1823179193Sjb * 1824179193Sjb * 2.7.2 Arguments and Notes 1825179193Sjb * 1826179193Sjb * The first argument is the provider identifier, as returned from a 1827179193Sjb * successful call to dtrace_register(). The second, third, and fourth 1828179193Sjb * arguments are the module name, function name, and probe name, 1829179193Sjb * respectively. Of these, module name and function name may both be NULL 1830179193Sjb * (in which case the probe is considered to be unanchored), or they may both 1831179193Sjb * be non-NULL. The name must be non-NULL, and must point to a non-empty 1832179193Sjb * string. 1833179193Sjb * 1834179193Sjb * The fifth argument is the number of artificial stack frames that will be 1835179193Sjb * found on the stack when dtrace_probe() is called for the new probe. These 1836179193Sjb * artificial frames will be automatically be pruned should the stack() or 1837179193Sjb * stackdepth() functions be called as part of one of the probe's ECBs. If 1838179193Sjb * the parameter doesn't add an artificial frame, this parameter should be 1839179193Sjb * zero. 1840179193Sjb * 1841179193Sjb * The final argument is a probe argument that will be passed back to the 1842179193Sjb * provider when a probe-specific operation is called. (e.g., via 1843179193Sjb * dtps_enable(), dtps_disable(), etc.) 1844179193Sjb * 1845179193Sjb * Note that it is up to the provider to be sure that the probe that it 1846179193Sjb * creates does not already exist -- if the provider is unsure of the probe's 1847179193Sjb * existence, it should assure its absence with dtrace_probe_lookup() before 1848179193Sjb * calling dtrace_probe_create(). 1849179193Sjb * 1850179193Sjb * 2.7.3 Return value 1851179193Sjb * 1852179193Sjb * dtrace_probe_create() always succeeds, and always returns the identifier 1853179193Sjb * of the newly-created probe. 1854179193Sjb * 1855179193Sjb * 2.7.4 Caller's context 1856179193Sjb * 1857179193Sjb * While dtrace_probe_create() is generally expected to be called from 1858179193Sjb * dtps_provide() and/or dtps_provide_module(), it may be called from other 1859179193Sjb * non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1860179193Sjb * 1861179193Sjb * 2.8 dtrace_id_t dtrace_probe_lookup(dtrace_provider_t id, const char *mod, 1862179193Sjb * const char *func, const char *name) 1863179193Sjb * 1864179193Sjb * 2.8.1 Overview 1865179193Sjb * 1866179193Sjb * Looks up a probe based on provdider and one or more of module name, 1867179193Sjb * function name and probe name. 1868179193Sjb * 1869179193Sjb * 2.8.2 Arguments and Notes 1870179193Sjb * 1871179193Sjb * The first argument is the provider identifier, as returned from a 1872179193Sjb * successful call to dtrace_register(). The second, third, and fourth 1873179193Sjb * arguments are the module name, function name, and probe name, 1874179193Sjb * respectively. Any of these may be NULL; dtrace_probe_lookup() will return 1875179193Sjb * the identifier of the first probe that is provided by the specified 1876179193Sjb * provider and matches all of the non-NULL matching criteria. 1877179193Sjb * dtrace_probe_lookup() is generally used by a provider to be check the 1878179193Sjb * existence of a probe before creating it with dtrace_probe_create(). 1879179193Sjb * 1880179193Sjb * 2.8.3 Return value 1881179193Sjb * 1882179193Sjb * If the probe exists, returns its identifier. If the probe does not exist, 1883179193Sjb * return DTRACE_IDNONE. 1884179193Sjb * 1885179193Sjb * 2.8.4 Caller's context 1886179193Sjb * 1887179193Sjb * While dtrace_probe_lookup() is generally expected to be called from 1888179193Sjb * dtps_provide() and/or dtps_provide_module(), it may also be called from 1889179193Sjb * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1890179193Sjb * 1891179193Sjb * 2.9 void *dtrace_probe_arg(dtrace_provider_t id, dtrace_id_t probe) 1892179193Sjb * 1893179193Sjb * 2.9.1 Overview 1894179193Sjb * 1895179193Sjb * Returns the probe argument associated with the specified probe. 1896179193Sjb * 1897179193Sjb * 2.9.2 Arguments and Notes 1898179193Sjb * 1899179193Sjb * The first argument is the provider identifier, as returned from a 1900179193Sjb * successful call to dtrace_register(). The second argument is a probe 1901179193Sjb * identifier, as returned from dtrace_probe_lookup() or 1902179193Sjb * dtrace_probe_create(). This is useful if a probe has multiple 1903179193Sjb * provider-specific components to it: the provider can create the probe 1904179193Sjb * once with provider-specific state, and then add to the state by looking 1905179193Sjb * up the probe based on probe identifier. 1906179193Sjb * 1907179193Sjb * 2.9.3 Return value 1908179193Sjb * 1909179193Sjb * Returns the argument associated with the specified probe. If the 1910179193Sjb * specified probe does not exist, or if the specified probe is not provided 1911179193Sjb * by the specified provider, NULL is returned. 1912179193Sjb * 1913179193Sjb * 2.9.4 Caller's context 1914179193Sjb * 1915179193Sjb * While dtrace_probe_arg() is generally expected to be called from 1916179193Sjb * dtps_provide() and/or dtps_provide_module(), it may also be called from 1917179193Sjb * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. 1918179193Sjb * 1919179193Sjb * 2.10 void dtrace_probe(dtrace_id_t probe, uintptr_t arg0, uintptr_t arg1, 1920179193Sjb * uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) 1921179193Sjb * 1922179193Sjb * 2.10.1 Overview 1923179193Sjb * 1924179193Sjb * The epicenter of DTrace: fires the specified probes with the specified 1925179193Sjb * arguments. 1926179193Sjb * 1927179193Sjb * 2.10.2 Arguments and Notes 1928179193Sjb * 1929179193Sjb * The first argument is a probe identifier as returned by 1930179193Sjb * dtrace_probe_create() or dtrace_probe_lookup(). The second through sixth 1931179193Sjb * arguments are the values to which the D variables "arg0" through "arg4" 1932179193Sjb * will be mapped. 1933179193Sjb * 1934179193Sjb * dtrace_probe() should be called whenever the specified probe has fired -- 1935179193Sjb * however the provider defines it. 1936179193Sjb * 1937179193Sjb * 2.10.3 Return value 1938179193Sjb * 1939179193Sjb * None. 1940179193Sjb * 1941179193Sjb * 2.10.4 Caller's context 1942179193Sjb * 1943179193Sjb * dtrace_probe() may be called in virtually any context: kernel, user, 1944179193Sjb * interrupt, high-level interrupt, with arbitrary adaptive locks held, with 1945179193Sjb * dispatcher locks held, with interrupts disabled, etc. The only latitude 1946179193Sjb * that must be afforded to DTrace is the ability to make calls within 1947179193Sjb * itself (and to its in-kernel subroutines) and the ability to access 1948179193Sjb * arbitrary (but mapped) memory. On some platforms, this constrains 1949179193Sjb * context. For example, on UltraSPARC, dtrace_probe() cannot be called 1950179193Sjb * from any context in which TL is greater than zero. dtrace_probe() may 1951179193Sjb * also not be called from any routine which may be called by dtrace_probe() 1952179193Sjb * -- which includes functions in the DTrace framework and some in-kernel 1953179193Sjb * DTrace subroutines. All such functions "dtrace_"; providers that 1954179193Sjb * instrument the kernel arbitrarily should be sure to not instrument these 1955179193Sjb * routines. 1956179193Sjb */ 1957179193Sjbtypedef struct dtrace_pops { 1958179193Sjb void (*dtps_provide)(void *arg, const dtrace_probedesc_t *spec); 1959179193Sjb void (*dtps_provide_module)(void *arg, struct modctl *mp); 1960179193Sjb void (*dtps_enable)(void *arg, dtrace_id_t id, void *parg); 1961179193Sjb void (*dtps_disable)(void *arg, dtrace_id_t id, void *parg); 1962179193Sjb void (*dtps_suspend)(void *arg, dtrace_id_t id, void *parg); 1963179193Sjb void (*dtps_resume)(void *arg, dtrace_id_t id, void *parg); 1964179193Sjb void (*dtps_getargdesc)(void *arg, dtrace_id_t id, void *parg, 1965179193Sjb dtrace_argdesc_t *desc); 1966179193Sjb uint64_t (*dtps_getargval)(void *arg, dtrace_id_t id, void *parg, 1967179193Sjb int argno, int aframes); 1968179193Sjb int (*dtps_usermode)(void *arg, dtrace_id_t id, void *parg); 1969179193Sjb void (*dtps_destroy)(void *arg, dtrace_id_t id, void *parg); 1970179193Sjb} dtrace_pops_t; 1971179193Sjb 1972179193Sjbtypedef uintptr_t dtrace_provider_id_t; 1973179193Sjb 1974179193Sjbextern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, 1975179193Sjb cred_t *, const dtrace_pops_t *, void *, dtrace_provider_id_t *); 1976179193Sjbextern int dtrace_unregister(dtrace_provider_id_t); 1977179193Sjbextern int dtrace_condense(dtrace_provider_id_t); 1978179193Sjbextern void dtrace_invalidate(dtrace_provider_id_t); 1979179193Sjbextern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, const char *, 1980179193Sjb const char *, const char *); 1981179193Sjbextern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *, 1982179193Sjb const char *, const char *, int, void *); 1983179193Sjbextern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t); 1984179193Sjbextern void dtrace_probe(dtrace_id_t, uintptr_t arg0, uintptr_t arg1, 1985179193Sjb uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); 1986179193Sjb 1987179193Sjb/* 1988179193Sjb * DTrace Meta Provider API 1989179193Sjb * 1990179193Sjb * The following functions are implemented by the DTrace framework and are 1991179193Sjb * used to implement meta providers. Meta providers plug into the DTrace 1992179193Sjb * framework and are used to instantiate new providers on the fly. At 1993179193Sjb * present, there is only one type of meta provider and only one meta 1994179193Sjb * provider may be registered with the DTrace framework at a time. The 1995179193Sjb * sole meta provider type provides user-land static tracing facilities 1996179193Sjb * by taking meta probe descriptions and adding a corresponding provider 1997179193Sjb * into the DTrace framework. 1998179193Sjb * 1999179193Sjb * 1 Framework-to-Provider 2000179193Sjb * 2001179193Sjb * 1.1 Overview 2002179193Sjb * 2003179193Sjb * The Framework-to-Provider API is represented by the dtrace_mops structure 2004179193Sjb * that the meta provider passes to the framework when registering itself as 2005179193Sjb * a meta provider. This structure consists of the following members: 2006179193Sjb * 2007179193Sjb * dtms_create_probe() <-- Add a new probe to a created provider 2008179193Sjb * dtms_provide_pid() <-- Create a new provider for a given process 2009179193Sjb * dtms_remove_pid() <-- Remove a previously created provider 2010179193Sjb * 2011179193Sjb * 1.2 void dtms_create_probe(void *arg, void *parg, 2012179193Sjb * dtrace_helper_probedesc_t *probedesc); 2013179193Sjb * 2014179193Sjb * 1.2.1 Overview 2015179193Sjb * 2016179193Sjb * Called by the DTrace framework to create a new probe in a provider 2017179193Sjb * created by this meta provider. 2018179193Sjb * 2019179193Sjb * 1.2.2 Arguments and notes 2020179193Sjb * 2021179193Sjb * The first argument is the cookie as passed to dtrace_meta_register(). 2022179193Sjb * The second argument is the provider cookie for the associated provider; 2023179193Sjb * this is obtained from the return value of dtms_provide_pid(). The third 2024179193Sjb * argument is the helper probe description. 2025179193Sjb * 2026179193Sjb * 1.2.3 Return value 2027179193Sjb * 2028179193Sjb * None 2029179193Sjb * 2030179193Sjb * 1.2.4 Caller's context 2031179193Sjb * 2032179193Sjb * dtms_create_probe() is called from either ioctl() or module load context. 2033179193Sjb * The DTrace framework is locked in such a way that meta providers may not 2034179193Sjb * register or unregister. This means that the meta provider cannot call 2035179193Sjb * dtrace_meta_register() or dtrace_meta_unregister(). However, the context is 2036179193Sjb * such that the provider may (and is expected to) call provider-related 2037179193Sjb * DTrace provider APIs including dtrace_probe_create(). 2038179193Sjb * 2039179193Sjb * 1.3 void *dtms_provide_pid(void *arg, dtrace_meta_provider_t *mprov, 2040179193Sjb * pid_t pid) 2041179193Sjb * 2042179193Sjb * 1.3.1 Overview 2043179193Sjb * 2044179193Sjb * Called by the DTrace framework to instantiate a new provider given the 2045179193Sjb * description of the provider and probes in the mprov argument. The 2046179193Sjb * meta provider should call dtrace_register() to insert the new provider 2047179193Sjb * into the DTrace framework. 2048179193Sjb * 2049179193Sjb * 1.3.2 Arguments and notes 2050179193Sjb * 2051179193Sjb * The first argument is the cookie as passed to dtrace_meta_register(). 2052179193Sjb * The second argument is a pointer to a structure describing the new 2053179193Sjb * helper provider. The third argument is the process identifier for 2054179193Sjb * process associated with this new provider. Note that the name of the 2055179193Sjb * provider as passed to dtrace_register() should be the contatenation of 2056179193Sjb * the dtmpb_provname member of the mprov argument and the processs 2057179193Sjb * identifier as a string. 2058179193Sjb * 2059179193Sjb * 1.3.3 Return value 2060179193Sjb * 2061179193Sjb * The cookie for the provider that the meta provider creates. This is 2062179193Sjb * the same value that it passed to dtrace_register(). 2063179193Sjb * 2064179193Sjb * 1.3.4 Caller's context 2065179193Sjb * 2066179193Sjb * dtms_provide_pid() is called from either ioctl() or module load context. 2067179193Sjb * The DTrace framework is locked in such a way that meta providers may not 2068179193Sjb * register or unregister. This means that the meta provider cannot call 2069179193Sjb * dtrace_meta_register() or dtrace_meta_unregister(). However, the context 2070179193Sjb * is such that the provider may -- and is expected to -- call 2071179193Sjb * provider-related DTrace provider APIs including dtrace_register(). 2072179193Sjb * 2073179193Sjb * 1.4 void dtms_remove_pid(void *arg, dtrace_meta_provider_t *mprov, 2074179193Sjb * pid_t pid) 2075179193Sjb * 2076179193Sjb * 1.4.1 Overview 2077179193Sjb * 2078179193Sjb * Called by the DTrace framework to remove a provider that had previously 2079179193Sjb * been instantiated via the dtms_provide_pid() entry point. The meta 2080179193Sjb * provider need not remove the provider immediately, but this entry 2081179193Sjb * point indicates that the provider should be removed as soon as possible 2082179193Sjb * using the dtrace_unregister() API. 2083179193Sjb * 2084179193Sjb * 1.4.2 Arguments and notes 2085179193Sjb * 2086179193Sjb * The first argument is the cookie as passed to dtrace_meta_register(). 2087179193Sjb * The second argument is a pointer to a structure describing the helper 2088179193Sjb * provider. The third argument is the process identifier for process 2089179193Sjb * associated with this new provider. 2090179193Sjb * 2091179193Sjb * 1.4.3 Return value 2092179193Sjb * 2093179193Sjb * None 2094179193Sjb * 2095179193Sjb * 1.4.4 Caller's context 2096179193Sjb * 2097179193Sjb * dtms_remove_pid() is called from either ioctl() or exit() context. 2098179193Sjb * The DTrace framework is locked in such a way that meta providers may not 2099179193Sjb * register or unregister. This means that the meta provider cannot call 2100179193Sjb * dtrace_meta_register() or dtrace_meta_unregister(). However, the context 2101179193Sjb * is such that the provider may -- and is expected to -- call 2102179193Sjb * provider-related DTrace provider APIs including dtrace_unregister(). 2103179193Sjb */ 2104179193Sjbtypedef struct dtrace_helper_probedesc { 2105179193Sjb char *dthpb_mod; /* probe module */ 2106179193Sjb char *dthpb_func; /* probe function */ 2107179193Sjb char *dthpb_name; /* probe name */ 2108179193Sjb uint64_t dthpb_base; /* base address */ 2109179193Sjb uint32_t *dthpb_offs; /* offsets array */ 2110179193Sjb uint32_t *dthpb_enoffs; /* is-enabled offsets array */ 2111179193Sjb uint32_t dthpb_noffs; /* offsets count */ 2112179193Sjb uint32_t dthpb_nenoffs; /* is-enabled offsets count */ 2113179193Sjb uint8_t *dthpb_args; /* argument mapping array */ 2114179193Sjb uint8_t dthpb_xargc; /* translated argument count */ 2115179193Sjb uint8_t dthpb_nargc; /* native argument count */ 2116179193Sjb char *dthpb_xtypes; /* translated types strings */ 2117179193Sjb char *dthpb_ntypes; /* native types strings */ 2118179193Sjb} dtrace_helper_probedesc_t; 2119179193Sjb 2120179193Sjbtypedef struct dtrace_helper_provdesc { 2121179193Sjb char *dthpv_provname; /* provider name */ 2122179193Sjb dtrace_pattr_t dthpv_pattr; /* stability attributes */ 2123179193Sjb} dtrace_helper_provdesc_t; 2124179193Sjb 2125179193Sjbtypedef struct dtrace_mops { 2126179193Sjb void (*dtms_create_probe)(void *, void *, dtrace_helper_probedesc_t *); 2127179193Sjb void *(*dtms_provide_pid)(void *, dtrace_helper_provdesc_t *, pid_t); 2128179193Sjb void (*dtms_remove_pid)(void *, dtrace_helper_provdesc_t *, pid_t); 2129179193Sjb} dtrace_mops_t; 2130179193Sjb 2131179193Sjbtypedef uintptr_t dtrace_meta_provider_id_t; 2132179193Sjb 2133179193Sjbextern int dtrace_meta_register(const char *, const dtrace_mops_t *, void *, 2134179193Sjb dtrace_meta_provider_id_t *); 2135179193Sjbextern int dtrace_meta_unregister(dtrace_meta_provider_id_t); 2136179193Sjb 2137179193Sjb/* 2138179193Sjb * DTrace Kernel Hooks 2139179193Sjb * 2140179193Sjb * The following functions are implemented by the base kernel and form a set of 2141179193Sjb * hooks used by the DTrace framework. DTrace hooks are implemented in either 2142179193Sjb * uts/common/os/dtrace_subr.c, an ISA-specific assembly file, or in a 2143179193Sjb * uts/<platform>/os/dtrace_subr.c corresponding to each hardware platform. 2144179193Sjb */ 2145179193Sjb 2146179193Sjbtypedef enum dtrace_vtime_state { 2147179193Sjb DTRACE_VTIME_INACTIVE = 0, /* No DTrace, no TNF */ 2148179193Sjb DTRACE_VTIME_ACTIVE, /* DTrace virtual time, no TNF */ 2149179193Sjb DTRACE_VTIME_INACTIVE_TNF, /* No DTrace, TNF active */ 2150179193Sjb DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ 2151179193Sjb} dtrace_vtime_state_t; 2152179193Sjb 2153179193Sjbextern dtrace_vtime_state_t dtrace_vtime_active; 2154179193Sjbextern void dtrace_vtime_switch(kthread_t *next); 2155179193Sjbextern void dtrace_vtime_enable_tnf(void); 2156179193Sjbextern void dtrace_vtime_disable_tnf(void); 2157179193Sjbextern void dtrace_vtime_enable(void); 2158179193Sjbextern void dtrace_vtime_disable(void); 2159179193Sjb 2160179193Sjbstruct regs; 2161179193Sjb 2162179193Sjbextern int (*dtrace_pid_probe_ptr)(struct regs *); 2163179193Sjbextern int (*dtrace_return_probe_ptr)(struct regs *); 2164179193Sjbextern void (*dtrace_fasttrap_fork_ptr)(proc_t *, proc_t *); 2165179193Sjbextern void (*dtrace_fasttrap_exec_ptr)(proc_t *); 2166179193Sjbextern void (*dtrace_fasttrap_exit_ptr)(proc_t *); 2167179193Sjbextern void dtrace_fasttrap_fork(proc_t *, proc_t *); 2168179193Sjb 2169179193Sjbtypedef uintptr_t dtrace_icookie_t; 2170179193Sjbtypedef void (*dtrace_xcall_t)(void *); 2171179193Sjb 2172179193Sjbextern dtrace_icookie_t dtrace_interrupt_disable(void); 2173179193Sjbextern void dtrace_interrupt_enable(dtrace_icookie_t); 2174179193Sjb 2175179193Sjbextern void dtrace_membar_producer(void); 2176179193Sjbextern void dtrace_membar_consumer(void); 2177179193Sjb 2178179193Sjbextern void (*dtrace_cpu_init)(processorid_t); 2179179193Sjbextern void (*dtrace_modload)(struct modctl *); 2180179193Sjbextern void (*dtrace_modunload)(struct modctl *); 2181179193Sjbextern void (*dtrace_helpers_cleanup)(); 2182179193Sjbextern void (*dtrace_helpers_fork)(proc_t *parent, proc_t *child); 2183179193Sjbextern void (*dtrace_cpustart_init)(); 2184179193Sjbextern void (*dtrace_cpustart_fini)(); 2185179193Sjb 2186179193Sjbextern void (*dtrace_debugger_init)(); 2187179193Sjbextern void (*dtrace_debugger_fini)(); 2188179193Sjbextern dtrace_cacheid_t dtrace_predcache_id; 2189179193Sjb 2190179193Sjbextern hrtime_t dtrace_gethrtime(void); 2191179193Sjbextern void dtrace_sync(void); 2192179193Sjbextern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); 2193179193Sjbextern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *); 2194179193Sjbextern void dtrace_vpanic(const char *, __va_list); 2195179193Sjbextern void dtrace_panic(const char *, ...); 2196179193Sjb 2197179193Sjbextern int dtrace_safe_defer_signal(void); 2198179193Sjbextern void dtrace_safe_synchronous_signal(void); 2199179193Sjb 2200179193Sjbextern int dtrace_mach_aframes(void); 2201179193Sjb 2202179193Sjb#if defined(__i386) || defined(__amd64) 2203179193Sjbextern int dtrace_instr_size(uchar_t *instr); 2204179193Sjbextern int dtrace_instr_size_isa(uchar_t *, model_t, int *); 2205179193Sjbextern void dtrace_invop_add(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 2206179193Sjbextern void dtrace_invop_remove(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 2207179193Sjbextern void dtrace_invop_callsite(void); 2208179193Sjb#endif 2209179193Sjb 2210179193Sjb#ifdef __sparc 2211179193Sjbextern int dtrace_blksuword32(uintptr_t, uint32_t *, int); 2212179193Sjbextern void dtrace_getfsr(uint64_t *); 2213179193Sjb#endif 2214179193Sjb 2215179193Sjb#define DTRACE_CPUFLAG_ISSET(flag) \ 2216179193Sjb (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & (flag)) 2217179193Sjb 2218179193Sjb#define DTRACE_CPUFLAG_SET(flag) \ 2219179193Sjb (cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= (flag)) 2220179193Sjb 2221179193Sjb#define DTRACE_CPUFLAG_CLEAR(flag) \ 2222179193Sjb (cpu_core[CPU->cpu_id].cpuc_dtrace_flags &= ~(flag)) 2223179193Sjb 2224179193Sjb#endif /* _KERNEL */ 2225179193Sjb 2226179193Sjb#endif /* _ASM */ 2227179193Sjb 2228179193Sjb#if defined(__i386) || defined(__amd64) 2229179193Sjb 2230179193Sjb#define DTRACE_INVOP_PUSHL_EBP 1 2231179193Sjb#define DTRACE_INVOP_POPL_EBP 2 2232179193Sjb#define DTRACE_INVOP_LEAVE 3 2233179193Sjb#define DTRACE_INVOP_NOP 4 2234179193Sjb#define DTRACE_INVOP_RET 5 2235179193Sjb 2236179193Sjb#endif 2237179193Sjb 2238179193Sjb#ifdef __cplusplus 2239179193Sjb} 2240179193Sjb#endif 2241179193Sjb 2242179193Sjb#endif /* _SYS_DTRACE_H */ 2243