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