4  * The contents of this file are subject to the terms of the 
   5  * Common Development and Distribution License (the "License"). 
   6  * You may not use this file except in compliance with the License. 
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 
   9  * or http://www.opensolaris.org/os/licensing. 
  10  * See the License for the specific language governing permissions 
  11  * and limitations under the License. 
  13  * When distributing Covered Code, include this CDDL HEADER in each 
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 
  15  * If applicable, add the following below this CDDL HEADER, with the 
  16  * fields enclosed by brackets "[]" replaced with your own identifying 
  17  * information: Portions Copyright [yyyy] [name of copyright owner] 
  23  * Portions copyright (c) 2013, Joyent, Inc. All rights reserved. 
  24  * Portions Copyright (c) 2013 by Delphix. All rights reserved. 
  28  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. 
  29  * Use is subject to license terms. 
  31  * Portions Copyright (c) 2012 by Delphix. All rights reserved. 
  37 /* #pragma ident        "@(#)dtrace.h   1.37    07/06/05 SMI" */ 
  44  * DTrace Dynamic Tracing Software: Kernel Interfaces 
  46  * Note: The contents of this file are private to the implementation of the 
  47  * Solaris system and DTrace subsystem and are subject to change at any time 
  48  * without notice.  Applications and drivers using these interfaces will fail 
  49  * to run on future releases.  These interfaces should not be used for any 
  50  * purpose except those expressly outlined in dtrace(7D) and libdtrace(3LIB). 
  51  * Please refer to the "Solaris Dynamic Tracing Guide" for more information. 
  56 #if !defined(__APPLE__) 
  57 #include <sys/types.h> 
  58 #include <sys/modctl.h> 
  59 #include <sys/processor.h> 
  60 #include <sys/systm.h> 
  61 #include <sys/ctf_api.h> 
  62 #include <sys/cyclic.h> 
  63 #include <sys/int_limits.h> 
  64 #else /* is Apple Mac OS X */ 
  68 #define _LP64 /* Solaris vs. Darwin */ 
  72 #define _ILP32 /* Solaris vs. Darwin */ 
  78 #define _KERNEL /* Solaris vs. Darwin */ 
  82 #if defined(__BIG_ENDIAN__) 
  83 #if !defined(_BIG_ENDIAN) 
  84 #define _BIG_ENDIAN /* Solaris vs. Darwin */ 
  86 #elif defined(__LITTLE_ENDIAN__) 
  87 #if !defined(_LITTLE_ENDIAN) 
  88 #define _LITTLE_ENDIAN /* Solaris vs. Darwin */ 
  91 #error Unknown endian-ness 
  94 #include <sys/types.h> 
  95 #include <sys/param.h> 
  99 #define NULL ((void *)0) /* quiets many warnings */ 
 103 #define MILLISEC        1000 
 104 #define MICROSEC        1000000 
 105 #define NANOSEC         1000000000 
 107 #define S_ROUND(x, a)   ((x) + (((a) ? (a) : 1) - 1) & ~(((a) ? (a) : 1) - 1)) 
 108 #define P2ROUNDUP(x, align)             (-(-(x) & -(align))) 
 109 #define P2PHASEUP(x, align, phase)      ((phase) - (((phase) - (x)) & -(align))) 
 111 #define CTF_MODEL_ILP32 1       /* object data model is ILP32 */ 
 112 #define CTF_MODEL_LP64  2       /* object data model is LP64 */ 
 114 #define CTF_MODEL_NATIVE        CTF_MODEL_LP64 
 116 #define CTF_MODEL_NATIVE        CTF_MODEL_ILP32 
 119 typedef uint8_t         uchar_t
; 
 120 typedef uint16_t        ushort_t
; 
 121 typedef uint32_t        uint_t
; 
 122 typedef unsigned long   ulong_t
; 
 123 typedef uint64_t        u_longlong_t
; 
 124 typedef int64_t         longlong_t
; 
 125 typedef int64_t         off64_t
; 
 126 typedef int                     processorid_t
; 
 127 typedef int64_t         hrtime_t
; 
 129 typedef enum { B_FALSE 
= 0, B_TRUE 
= 1 } _dtrace_boolean
; 
 131 typedef uint8_t UUID
[16]; /* For modctl use in dtrace.h */ 
 133 struct modctl
; /* In lieu of Solaris <sys/modctl.h> */ 
 134 /* NOTHING */  /* In lieu of Solaris <sys/processor.h> */ 
 135 #include <sys/ioctl.h> /* In lieu of Solaris <sys/systm.h> */ 
 137 /* NOTHING */ /* In lieu of Solaris <sys/ctf_api.h> */ 
 139 /* In lieu of Solaris <sys/ctf_api.h> */ 
 140 typedef struct ctf_file ctf_file_t
; 
 141 typedef long ctf_id_t
; 
 143 /* NOTHING */ /* In lieu of Solaris <sys/cyclic.h> */ 
 144 /* NOTHING */ /* In lieu of Solaris <sys/int_limits.h> */ 
 146 typedef uint32_t        zoneid_t
; 
 148 #include <sys/dtrace_glue.h> 
 151 typedef va_list __va_list
; 
 153 /* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */ 
 154 #define proc_t struct proc /* Steer clear of the Darwin typedef for proc_t */ 
 155 #endif /* __APPLE__ */ 
 158  * DTrace Universal Constants and Typedefs 
 160 #define DTRACE_CPUALL           -1      /* all CPUs */ 
 161 #define DTRACE_IDNONE           0       /* invalid probe identifier */ 
 162 #define DTRACE_EPIDNONE         0       /* invalid enabled probe identifier */ 
 163 #define DTRACE_AGGIDNONE        0       /* invalid aggregation identifier */ 
 164 #define DTRACE_AGGVARIDNONE     0       /* invalid aggregation variable ID */ 
 165 #define DTRACE_CACHEIDNONE      0       /* invalid predicate cache */ 
 166 #define DTRACE_PROVNONE         0       /* invalid provider identifier */ 
 167 #define DTRACE_METAPROVNONE     0       /* invalid meta-provider identifier */ 
 168 #define DTRACE_ARGNONE          -1      /* invalid argument index */ 
 170 #define DTRACE_PROVNAMELEN      64 
 171 #define DTRACE_MODNAMELEN       64 
 172 #define DTRACE_FUNCNAMELEN      128 
 173 #define DTRACE_NAMELEN          64 
 174 #define DTRACE_FULLNAMELEN      (DTRACE_PROVNAMELEN + DTRACE_MODNAMELEN + \ 
 175                                 DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 4) 
 176 #define DTRACE_ARGTYPELEN       128 
 178 typedef uint32_t dtrace_id_t
;           /* probe identifier */ 
 179 typedef uint32_t dtrace_epid_t
;         /* enabled probe identifier */ 
 180 typedef uint32_t dtrace_aggid_t
;        /* aggregation identifier */ 
 181 typedef int64_t dtrace_aggvarid_t
;      /* aggregation variable identifier */ 
 182 typedef uint16_t dtrace_actkind_t
;      /* action kind */ 
 183 typedef int64_t dtrace_optval_t
;        /* option value */ 
 184 typedef uint32_t dtrace_cacheid_t
;      /* predicate cache identifier */ 
 186 typedef enum dtrace_probespec 
{ 
 187         DTRACE_PROBESPEC_NONE 
= -1, 
 188         DTRACE_PROBESPEC_PROVIDER 
= 0, 
 189         DTRACE_PROBESPEC_MOD
, 
 190         DTRACE_PROBESPEC_FUNC
, 
 191         DTRACE_PROBESPEC_NAME
 
 192 } dtrace_probespec_t
; 
 195  * DTrace Intermediate Format (DIF) 
 197  * The following definitions describe the DTrace Intermediate Format (DIF), a 
 198  * a RISC-like instruction set and program encoding used to represent 
 199  * predicates and actions that can be bound to DTrace probes.  The constants 
 200  * below defining the number of available registers are suggested minimums; the 
 201  * compiler should use DTRACEIOC_CONF to dynamically obtain the number of 
 202  * registers provided by the current DTrace implementation. 
 204 #define DIF_VERSION_1   1               /* DIF version 1: Solaris 10 Beta */ 
 205 #define DIF_VERSION_2   2               /* DIF version 2: Solaris 10 FCS */ 
 206 #define DIF_VERSION     DIF_VERSION_2   /* latest DIF instruction set version */ 
 207 #define DIF_DIR_NREGS   8               /* number of DIF integer registers */ 
 208 #define DIF_DTR_NREGS   8               /* number of DIF tuple registers */ 
 210 #define DIF_OP_OR       1               /* or   r1, r2, rd */ 
 211 #define DIF_OP_XOR      2               /* xor  r1, r2, rd */ 
 212 #define DIF_OP_AND      3               /* and  r1, r2, rd */ 
 213 #define DIF_OP_SLL      4               /* sll  r1, r2, rd */ 
 214 #define DIF_OP_SRL      5               /* srl  r1, r2, rd */ 
 215 #define DIF_OP_SUB      6               /* sub  r1, r2, rd */ 
 216 #define DIF_OP_ADD      7               /* add  r1, r2, rd */ 
 217 #define DIF_OP_MUL      8               /* mul  r1, r2, rd */ 
 218 #define DIF_OP_SDIV     9               /* sdiv r1, r2, rd */ 
 219 #define DIF_OP_UDIV     10              /* udiv r1, r2, rd */ 
 220 #define DIF_OP_SREM     11              /* srem r1, r2, rd */ 
 221 #define DIF_OP_UREM     12              /* urem r1, r2, rd */ 
 222 #define DIF_OP_NOT      13              /* not  r1, rd */ 
 223 #define DIF_OP_MOV      14              /* mov  r1, rd */ 
 224 #define DIF_OP_CMP      15              /* cmp  r1, r2 */ 
 225 #define DIF_OP_TST      16              /* tst  r1 */ 
 226 #define DIF_OP_BA       17              /* ba   label */ 
 227 #define DIF_OP_BE       18              /* be   label */ 
 228 #define DIF_OP_BNE      19              /* bne  label */ 
 229 #define DIF_OP_BG       20              /* bg   label */ 
 230 #define DIF_OP_BGU      21              /* bgu  label */ 
 231 #define DIF_OP_BGE      22              /* bge  label */ 
 232 #define DIF_OP_BGEU     23              /* bgeu label */ 
 233 #define DIF_OP_BL       24              /* bl   label */ 
 234 #define DIF_OP_BLU      25              /* blu  label */ 
 235 #define DIF_OP_BLE      26              /* ble  label */ 
 236 #define DIF_OP_BLEU     27              /* bleu label */ 
 237 #define DIF_OP_LDSB     28              /* ldsb [r1], rd */ 
 238 #define DIF_OP_LDSH     29              /* ldsh [r1], rd */ 
 239 #define DIF_OP_LDSW     30              /* ldsw [r1], rd */ 
 240 #define DIF_OP_LDUB     31              /* ldub [r1], rd */ 
 241 #define DIF_OP_LDUH     32              /* lduh [r1], rd */ 
 242 #define DIF_OP_LDUW     33              /* lduw [r1], rd */ 
 243 #define DIF_OP_LDX      34              /* ldx  [r1], rd */ 
 244 #define DIF_OP_RET      35              /* ret  rd */ 
 245 #define DIF_OP_NOP      36              /* nop */ 
 246 #define DIF_OP_SETX     37              /* setx intindex, rd */ 
 247 #define DIF_OP_SETS     38              /* sets strindex, rd */ 
 248 #define DIF_OP_SCMP     39              /* scmp r1, r2 */ 
 249 #define DIF_OP_LDGA     40              /* ldga var, ri, rd */ 
 250 #define DIF_OP_LDGS     41              /* ldgs var, rd */ 
 251 #define DIF_OP_STGS     42              /* stgs var, rs */ 
 252 #define DIF_OP_LDTA     43              /* ldta var, ri, rd */ 
 253 #define DIF_OP_LDTS     44              /* ldts var, rd */ 
 254 #define DIF_OP_STTS     45              /* stts var, rs */ 
 255 #define DIF_OP_SRA      46              /* sra  r1, r2, rd */ 
 256 #define DIF_OP_CALL     47              /* call subr, rd */ 
 257 #define DIF_OP_PUSHTR   48              /* pushtr type, rs, rr */ 
 258 #define DIF_OP_PUSHTV   49              /* pushtv type, rs, rv */ 
 259 #define DIF_OP_POPTS    50              /* popts */ 
 260 #define DIF_OP_FLUSHTS  51              /* flushts */ 
 261 #define DIF_OP_LDGAA    52              /* ldgaa var, rd */ 
 262 #define DIF_OP_LDTAA    53              /* ldtaa var, rd */ 
 263 #define DIF_OP_STGAA    54              /* stgaa var, rs */ 
 264 #define DIF_OP_STTAA    55              /* sttaa var, rs */ 
 265 #define DIF_OP_LDLS     56              /* ldls var, rd */ 
 266 #define DIF_OP_STLS     57              /* stls var, rs */ 
 267 #define DIF_OP_ALLOCS   58              /* allocs r1, rd */ 
 268 #define DIF_OP_COPYS    59              /* copys  r1, r2, rd */ 
 269 #define DIF_OP_STB      60              /* stb  r1, [rd] */ 
 270 #define DIF_OP_STH      61              /* sth  r1, [rd] */ 
 271 #define DIF_OP_STW      62              /* stw  r1, [rd] */ 
 272 #define DIF_OP_STX      63              /* stx  r1, [rd] */ 
 273 #define DIF_OP_ULDSB    64              /* uldsb [r1], rd */ 
 274 #define DIF_OP_ULDSH    65              /* uldsh [r1], rd */ 
 275 #define DIF_OP_ULDSW    66              /* uldsw [r1], rd */ 
 276 #define DIF_OP_ULDUB    67              /* uldub [r1], rd */ 
 277 #define DIF_OP_ULDUH    68              /* ulduh [r1], rd */ 
 278 #define DIF_OP_ULDUW    69              /* ulduw [r1], rd */ 
 279 #define DIF_OP_ULDX     70              /* uldx  [r1], rd */ 
 280 #define DIF_OP_RLDSB    71              /* rldsb [r1], rd */ 
 281 #define DIF_OP_RLDSH    72              /* rldsh [r1], rd */ 
 282 #define DIF_OP_RLDSW    73              /* rldsw [r1], rd */ 
 283 #define DIF_OP_RLDUB    74              /* rldub [r1], rd */ 
 284 #define DIF_OP_RLDUH    75              /* rlduh [r1], rd */ 
 285 #define DIF_OP_RLDUW    76              /* rlduw [r1], rd */ 
 286 #define DIF_OP_RLDX     77              /* rldx  [r1], rd */ 
 287 #define DIF_OP_XLATE    78              /* xlate xlrindex, rd */ 
 288 #define DIF_OP_XLARG    79              /* xlarg xlrindex, rd */ 
 290 #define DIF_INTOFF_MAX          0xffff  /* highest integer table offset */ 
 291 #define DIF_STROFF_MAX          0xffff  /* highest string table offset */ 
 292 #define DIF_REGISTER_MAX        0xff    /* highest register number */ 
 293 #define DIF_VARIABLE_MAX        0xffff  /* highest variable identifier */ 
 294 #define DIF_SUBROUTINE_MAX      0xffff  /* highest subroutine code */ 
 296 #define DIF_VAR_ARRAY_MIN       0x0000  /* lowest numbered array variable */ 
 297 #define DIF_VAR_ARRAY_UBASE     0x0080  /* lowest user-defined array */ 
 298 #define DIF_VAR_ARRAY_MAX       0x00ff  /* highest numbered array variable */ 
 300 #define DIF_VAR_OTHER_MIN       0x0100  /* lowest numbered scalar or assc */ 
 301 #define DIF_VAR_OTHER_UBASE     0x0500  /* lowest user-defined scalar or assc */ 
 302 #define DIF_VAR_OTHER_MAX       0xffff  /* highest numbered scalar or assc */ 
 304 #define DIF_VAR_ARGS            0x0000  /* arguments array */ 
 305 #define DIF_VAR_REGS            0x0001  /* registers array */ 
 306 #define DIF_VAR_UREGS           0x0002  /* user registers array */ 
 307 #define DIF_VAR_CURTHREAD       0x0100  /* thread pointer */ 
 308 #define DIF_VAR_TIMESTAMP       0x0101  /* timestamp */ 
 309 #define DIF_VAR_VTIMESTAMP      0x0102  /* virtual timestamp */ 
 310 #define DIF_VAR_IPL             0x0103  /* interrupt priority level */ 
 311 #define DIF_VAR_EPID            0x0104  /* enabled probe ID */ 
 312 #define DIF_VAR_ID              0x0105  /* probe ID */ 
 313 #define DIF_VAR_ARG0            0x0106  /* first argument */ 
 314 #define DIF_VAR_ARG1            0x0107  /* second argument */ 
 315 #define DIF_VAR_ARG2            0x0108  /* third argument */ 
 316 #define DIF_VAR_ARG3            0x0109  /* fourth argument */ 
 317 #define DIF_VAR_ARG4            0x010a  /* fifth argument */ 
 318 #define DIF_VAR_ARG5            0x010b  /* sixth argument */ 
 319 #define DIF_VAR_ARG6            0x010c  /* seventh argument */ 
 320 #define DIF_VAR_ARG7            0x010d  /* eighth argument */ 
 321 #define DIF_VAR_ARG8            0x010e  /* ninth argument */ 
 322 #define DIF_VAR_ARG9            0x010f  /* tenth argument */ 
 323 #define DIF_VAR_STACKDEPTH      0x0110  /* stack depth */ 
 324 #define DIF_VAR_CALLER          0x0111  /* caller */ 
 325 #define DIF_VAR_PROBEPROV       0x0112  /* probe provider */ 
 326 #define DIF_VAR_PROBEMOD        0x0113  /* probe module */ 
 327 #define DIF_VAR_PROBEFUNC       0x0114  /* probe function */ 
 328 #define DIF_VAR_PROBENAME       0x0115  /* probe name */ 
 329 #define DIF_VAR_PID             0x0116  /* process ID */ 
 330 #define DIF_VAR_TID             0x0117  /* (per-process) thread ID */ 
 331 #define DIF_VAR_EXECNAME        0x0118  /* name of executable */ 
 332 #define DIF_VAR_ZONENAME        0x0119  /* zone name associated with process */ 
 333 #define DIF_VAR_WALLTIMESTAMP   0x011a  /* wall-clock timestamp */ 
 334 #define DIF_VAR_USTACKDEPTH     0x011b  /* user-land stack depth */ 
 335 #define DIF_VAR_UCALLER         0x011c  /* user-level caller */ 
 336 #define DIF_VAR_PPID            0x011d  /* parent process ID */ 
 337 #define DIF_VAR_UID             0x011e  /* process user ID */ 
 338 #define DIF_VAR_GID             0x011f  /* process group ID */ 
 339 #define DIF_VAR_ERRNO           0x0120  /* thread errno */ 
 340 #if defined(__APPLE__) 
 341 #define DIF_VAR_PTHREAD_SELF    0x0200  /* Apple specific PTHREAD_SELF (Not currently supported!) */ 
 342 #define DIF_VAR_DISPATCHQADDR   0x0201  /* Apple specific dispatch queue addr */ 
 343 #define DIF_VAR_MACHTIMESTAMP   0x0202  /* mach_absolute_timestamp() */ 
 344 #define DIF_VAR_CPU             0x0203  /* cpu number */ 
 345 #endif /* __APPLE __ */ 
 347 #define DIF_SUBR_RAND                   0 
 348 #define DIF_SUBR_MUTEX_OWNED            1 
 349 #define DIF_SUBR_MUTEX_OWNER            2 
 350 #define DIF_SUBR_MUTEX_TYPE_ADAPTIVE    3 
 351 #define DIF_SUBR_MUTEX_TYPE_SPIN        4 
 352 #define DIF_SUBR_RW_READ_HELD           5 
 353 #define DIF_SUBR_RW_WRITE_HELD          6 
 354 #define DIF_SUBR_RW_ISWRITER            7 
 355 #define DIF_SUBR_COPYIN                 8 
 356 #define DIF_SUBR_COPYINSTR              9 
 357 #define DIF_SUBR_SPECULATION            10 
 358 #define DIF_SUBR_PROGENYOF              11 
 359 #define DIF_SUBR_STRLEN                 12 
 360 #define DIF_SUBR_COPYOUT                13 
 361 #define DIF_SUBR_COPYOUTSTR             14 
 362 #define DIF_SUBR_ALLOCA                 15 
 363 #define DIF_SUBR_BCOPY                  16 
 364 #define DIF_SUBR_COPYINTO               17 
 365 #define DIF_SUBR_MSGDSIZE               18 
 366 #define DIF_SUBR_MSGSIZE                19 
 367 #define DIF_SUBR_GETMAJOR               20 
 368 #define DIF_SUBR_GETMINOR               21 
 369 #define DIF_SUBR_DDI_PATHNAME           22 
 370 #define DIF_SUBR_STRJOIN                23 
 371 #define DIF_SUBR_LLTOSTR                24 
 372 #define DIF_SUBR_BASENAME               25 
 373 #define DIF_SUBR_DIRNAME                26 
 374 #define DIF_SUBR_CLEANPATH              27 
 375 #define DIF_SUBR_STRCHR                 28 
 376 #define DIF_SUBR_STRRCHR                29 
 377 #define DIF_SUBR_STRSTR                 30 
 378 #define DIF_SUBR_STRTOK                 31 
 379 #define DIF_SUBR_SUBSTR                 32 
 380 #define DIF_SUBR_INDEX                  33 
 381 #define DIF_SUBR_RINDEX                 34 
 382 #define DIF_SUBR_HTONS                  35 
 383 #define DIF_SUBR_HTONL                  36 
 384 #define DIF_SUBR_HTONLL                 37 
 385 #define DIF_SUBR_NTOHS                  38 
 386 #define DIF_SUBR_NTOHL                  39 
 387 #define DIF_SUBR_NTOHLL                 40 
 388 #define DIF_SUBR_INET_NTOP              41 
 389 #define DIF_SUBR_INET_NTOA              42 
 390 #define DIF_SUBR_INET_NTOA6             43 
 391 #define DIF_SUBR_TOUPPER                44 
 392 #define DIF_SUBR_TOLOWER                45 
 393 #define DIF_SUBR_MAX                    46      /* max subroutine value */ 
 395 /* Apple-specific subroutines */ 
 396 #if defined(__APPLE__) 
 397 #define DIF_SUBR_APPLE_MIN              200     /* min apple-specific subroutine value */ 
 398 #define DIF_SUBR_VM_KERNEL_ADDRPERM     200 
 399 #define DIF_SUBR_KDEBUG_TRACE           201 
 400 #define DIF_SUBR_KDEBUG_TRACE_STRING    202 
 401 #define DIF_SUBR_APPLE_MAX              202      /* max apple-specific subroutine value */ 
 402 #endif /* __APPLE__ */ 
 404 typedef uint32_t dif_instr_t
; 
 406 #define DIF_INSTR_OP(i)                 (((i) >> 24) & 0xff) 
 407 #define DIF_INSTR_R1(i)                 (((i) >> 16) & 0xff) 
 408 #define DIF_INSTR_R2(i)                 (((i) >>  8) & 0xff) 
 409 #define DIF_INSTR_RD(i)                 ((i) & 0xff) 
 410 #define DIF_INSTR_RS(i)                 ((i) & 0xff) 
 411 #define DIF_INSTR_LABEL(i)              ((i) & 0xffffff) 
 412 #define DIF_INSTR_VAR(i)                (((i) >>  8) & 0xffff) 
 413 #define DIF_INSTR_INTEGER(i)            (((i) >>  8) & 0xffff) 
 414 #define DIF_INSTR_STRING(i)             (((i) >>  8) & 0xffff) 
 415 #define DIF_INSTR_SUBR(i)               (((i) >>  8) & 0xffff) 
 416 #define DIF_INSTR_TYPE(i)               (((i) >> 16) & 0xff) 
 417 #define DIF_INSTR_XLREF(i)              (((i) >>  8) & 0xffff) 
 419 #define DIF_INSTR_FMT(op, r1, r2, d) \ 
 420         (((op) << 24) | ((r1) << 16) | ((r2) << 8) | (d)) 
 422 #define DIF_INSTR_NOT(r1, d)            (DIF_INSTR_FMT(DIF_OP_NOT, r1, 0, d)) 
 423 #define DIF_INSTR_MOV(r1, d)            (DIF_INSTR_FMT(DIF_OP_MOV, r1, 0, d)) 
 424 #define DIF_INSTR_CMP(op, r1, r2)       (DIF_INSTR_FMT(op, r1, r2, 0)) 
 425 #define DIF_INSTR_TST(r1)               (DIF_INSTR_FMT(DIF_OP_TST, r1, 0, 0)) 
 426 #define DIF_INSTR_BRANCH(op, label)     (((op) << 24) | (label)) 
 427 #define DIF_INSTR_LOAD(op, r1, d)       (DIF_INSTR_FMT(op, r1, 0, d)) 
 428 #define DIF_INSTR_STORE(op, r1, d)      (DIF_INSTR_FMT(op, r1, 0, d)) 
 429 #define DIF_INSTR_SETX(i, d)            ((DIF_OP_SETX << 24) | ((i) << 8) | (d)) 
 430 #define DIF_INSTR_SETS(s, d)            ((DIF_OP_SETS << 24) | ((s) << 8) | (d)) 
 431 #define DIF_INSTR_RET(d)                (DIF_INSTR_FMT(DIF_OP_RET, 0, 0, d)) 
 432 #define DIF_INSTR_NOP                   (DIF_OP_NOP << 24) 
 433 #define DIF_INSTR_LDA(op, v, r, d)      (DIF_INSTR_FMT(op, v, r, d)) 
 434 #define DIF_INSTR_LDV(op, v, d)         (((op) << 24) | ((v) << 8) | (d)) 
 435 #define DIF_INSTR_STV(op, v, rs)        (((op) << 24) | ((v) << 8) | (rs)) 
 436 #define DIF_INSTR_CALL(s, d)            ((DIF_OP_CALL << 24) | ((s) << 8) | (d)) 
 437 #define DIF_INSTR_PUSHTS(op, t, r2, rs) (DIF_INSTR_FMT(op, t, r2, rs)) 
 438 #define DIF_INSTR_POPTS                 (DIF_OP_POPTS << 24) 
 439 #define DIF_INSTR_FLUSHTS               (DIF_OP_FLUSHTS << 24) 
 440 #define DIF_INSTR_ALLOCS(r1, d)         (DIF_INSTR_FMT(DIF_OP_ALLOCS, r1, 0, d)) 
 441 #define DIF_INSTR_COPYS(r1, r2, d)      (DIF_INSTR_FMT(DIF_OP_COPYS, r1, r2, d)) 
 442 #define DIF_INSTR_XLATE(op, r, d)       (((op) << 24) | ((r) << 8) | (d)) 
 444 #define DIF_REG_R0      0               /* %r0 is always set to zero */ 
 447  * A DTrace Intermediate Format Type (DIF Type) is used to represent the types 
 448  * of variables, function and associative array arguments, and the return type 
 449  * for each DIF object (shown below).  It contains a description of the type, 
 450  * its size in bytes, and a module identifier. 
 452 typedef struct dtrace_diftype 
{ 
 453         uint8_t dtdt_kind
;              /* type kind (see below) */ 
 454         uint8_t dtdt_ckind
;             /* type kind in CTF */ 
 455         uint8_t dtdt_flags
;             /* type flags (see below) */ 
 456         uint8_t dtdt_pad
;               /* reserved for future use */ 
 457         uint32_t dtdt_size
;             /* type size in bytes (unless string) */ 
 460 #define DIF_TYPE_CTF            0       /* type is a CTF type */ 
 461 #define DIF_TYPE_STRING         1       /* type is a D string */ 
 463 #define DIF_TF_BYREF            0x1     /* type is passed by reference */ 
 464 #define DIF_TF_BYUREF           0x2     /* user type is passed by reference */ 
 467  * A DTrace Intermediate Format variable record is used to describe each of the 
 468  * variables referenced by a given DIF object.  It contains an integer variable 
 469  * identifier along with variable scope and properties, as shown below.  The 
 470  * size of this structure must be sizeof (int) aligned. 
 472 typedef struct dtrace_difv 
{ 
 473         uint32_t dtdv_name
;             /* variable name index in dtdo_strtab */ 
 474         uint32_t dtdv_id
;               /* variable reference identifier */ 
 475         uint8_t dtdv_kind
;              /* variable kind (see below) */ 
 476         uint8_t dtdv_scope
;             /* variable scope (see below) */ 
 477         uint16_t dtdv_flags
;            /* variable flags (see below) */ 
 478         dtrace_diftype_t dtdv_type
;     /* variable type (see above) */ 
 481 #define DIFV_KIND_ARRAY         0       /* variable is an array of quantities */ 
 482 #define DIFV_KIND_SCALAR        1       /* variable is a scalar quantity */ 
 484 #define DIFV_SCOPE_GLOBAL       0       /* variable has global scope */ 
 485 #define DIFV_SCOPE_THREAD       1       /* variable has thread scope */ 
 486 #define DIFV_SCOPE_LOCAL        2       /* variable has local scope */ 
 488 #define DIFV_F_REF              0x1     /* variable is referenced by DIFO */ 
 489 #define DIFV_F_MOD              0x2     /* variable is written by DIFO */ 
 494  * The upper byte determines the class of the action; the low bytes determines 
 495  * the specific action within that class.  The classes of actions are as 
 498  *   [ no class ]                  <= May record process- or kernel-related data 
 499  *   DTRACEACT_PROC                <= Only records process-related data 
 500  *   DTRACEACT_PROC_DESTRUCTIVE    <= Potentially destructive to processes 
 501  *   DTRACEACT_KERNEL              <= Only records kernel-related data 
 502  *   DTRACEACT_KERNEL_DESTRUCTIVE  <= Potentially destructive to the kernel 
 503  *   DTRACEACT_SPECULATIVE         <= Speculation-related action 
 504  *   DTRACEACT_AGGREGATION         <= Aggregating action 
 506 #define DTRACEACT_NONE                  0       /* no action */ 
 507 #define DTRACEACT_DIFEXPR               1       /* action is DIF expression */ 
 508 #define DTRACEACT_EXIT                  2       /* exit() action */ 
 509 #define DTRACEACT_PRINTF                3       /* printf() action */ 
 510 #define DTRACEACT_PRINTA                4       /* printa() action */ 
 511 #define DTRACEACT_LIBACT                5       /* library-controlled action */ 
 512 #define DTRACEACT_TRACEMEM              6       /* tracemem() action */ 
 513 #define DTRACEACT_TRACEMEM_DYNSIZE      7       /* dynamic tracemem() size */ 
 515 #if defined(__APPLE__) 
 516 #define DTRACEACT_APPLEBINARY           50      /* Apple DT perf. tool action */ 
 517 #endif /* __APPLE__ */ 
 519 #define DTRACEACT_PROC                  0x0100 
 520 #define DTRACEACT_USTACK                (DTRACEACT_PROC + 1) 
 521 #define DTRACEACT_JSTACK                (DTRACEACT_PROC + 2) 
 522 #define DTRACEACT_USYM                  (DTRACEACT_PROC + 3) 
 523 #define DTRACEACT_UMOD                  (DTRACEACT_PROC + 4) 
 524 #define DTRACEACT_UADDR                 (DTRACEACT_PROC + 5) 
 526 #define DTRACEACT_PROC_DESTRUCTIVE      0x0200 
 527 #define DTRACEACT_STOP                  (DTRACEACT_PROC_DESTRUCTIVE + 1) 
 528 #define DTRACEACT_RAISE                 (DTRACEACT_PROC_DESTRUCTIVE + 2) 
 529 #define DTRACEACT_SYSTEM                (DTRACEACT_PROC_DESTRUCTIVE + 3) 
 530 #define DTRACEACT_FREOPEN               (DTRACEACT_PROC_DESTRUCTIVE + 4) 
 532 #if defined(__APPLE__) 
 534  * Dtrace stop() will task_suspend the currently running process. 
 535  * Dtrace pidresume(pid) will task_resume it. 
 538 #define DTRACEACT_PIDRESUME             (DTRACEACT_PROC_DESTRUCTIVE + 50) 
 539 #endif /* __APPLE__ */   
 541 #define DTRACEACT_PROC_CONTROL          0x0300 
 543 #define DTRACEACT_KERNEL                0x0400 
 544 #define DTRACEACT_STACK                 (DTRACEACT_KERNEL + 1) 
 545 #define DTRACEACT_SYM                   (DTRACEACT_KERNEL + 2) 
 546 #define DTRACEACT_MOD                   (DTRACEACT_KERNEL + 3) 
 548 #define DTRACEACT_KERNEL_DESTRUCTIVE    0x0500 
 549 #define DTRACEACT_BREAKPOINT            (DTRACEACT_KERNEL_DESTRUCTIVE + 1) 
 550 #define DTRACEACT_PANIC                 (DTRACEACT_KERNEL_DESTRUCTIVE + 2) 
 551 #define DTRACEACT_CHILL                 (DTRACEACT_KERNEL_DESTRUCTIVE + 3) 
 553 #define DTRACEACT_SPECULATIVE           0x0600 
 554 #define DTRACEACT_SPECULATE             (DTRACEACT_SPECULATIVE + 1) 
 555 #define DTRACEACT_COMMIT                (DTRACEACT_SPECULATIVE + 2) 
 556 #define DTRACEACT_DISCARD               (DTRACEACT_SPECULATIVE + 3) 
 558 #define DTRACEACT_CLASS(x)              ((x) & 0xff00) 
 560 #define DTRACEACT_ISDESTRUCTIVE(x)      \ 
 561         (DTRACEACT_CLASS(x) == DTRACEACT_PROC_DESTRUCTIVE || \ 
 562         DTRACEACT_CLASS(x) == DTRACEACT_KERNEL_DESTRUCTIVE) 
 564 #define DTRACEACT_ISSPECULATIVE(x)      \ 
 565         (DTRACEACT_CLASS(x) == DTRACEACT_SPECULATIVE) 
 567 #define DTRACEACT_ISPRINTFLIKE(x)       \ 
 568         ((x) == DTRACEACT_PRINTF || (x) == DTRACEACT_PRINTA || \ 
 569         (x) == DTRACEACT_SYSTEM || (x) == DTRACEACT_FREOPEN) 
 572  * DTrace Aggregating Actions 
 574  * These are functions f(x) for which the following is true: 
 576  *    f(f(x_0) U f(x_1) U ... U f(x_n)) = f(x_0 U x_1 U ... U x_n) 
 578  * where x_n is a set of arbitrary data.  Aggregating actions are in their own 
 579  * DTrace action class, DTTRACEACT_AGGREGATION.  The macros provided here allow 
 580  * for easier processing of the aggregation argument and data payload for a few 
 581  * aggregating actions (notably:  quantize(), lquantize(), and ustack()). 
 583 #define DTRACEACT_AGGREGATION           0x0700 
 584 #define DTRACEAGG_COUNT                 (DTRACEACT_AGGREGATION + 1) 
 585 #define DTRACEAGG_MIN                   (DTRACEACT_AGGREGATION + 2) 
 586 #define DTRACEAGG_MAX                   (DTRACEACT_AGGREGATION + 3) 
 587 #define DTRACEAGG_AVG                   (DTRACEACT_AGGREGATION + 4) 
 588 #define DTRACEAGG_SUM                   (DTRACEACT_AGGREGATION + 5) 
 589 #define DTRACEAGG_STDDEV                (DTRACEACT_AGGREGATION + 6) 
 590 #define DTRACEAGG_QUANTIZE              (DTRACEACT_AGGREGATION + 7) 
 591 #define DTRACEAGG_LQUANTIZE             (DTRACEACT_AGGREGATION + 8) 
 592 #define DTRACEAGG_LLQUANTIZE            (DTRACEACT_AGGREGATION + 9) 
 594 #define DTRACEACT_ISAGG(x)              \ 
 595         (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION) 
 597 #if !defined(__APPLE__)  /* Quiet compiler warning. */ 
 598 #define DTRACE_QUANTIZE_NBUCKETS        \ 
 599         (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) 
 601 #define DTRACE_QUANTIZE_ZEROBUCKET      ((sizeof (uint64_t) * NBBY) - 1) 
 603 #define DTRACE_QUANTIZE_NBUCKETS        \ 
 604         (int)(((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) 
 606 #define DTRACE_QUANTIZE_ZEROBUCKET      (int64_t)((sizeof (uint64_t) * NBBY) - 1) 
 607 #endif /* __APPLE __*/ 
 609 #define DTRACE_QUANTIZE_BUCKETVAL(buck)                                 \ 
 610         (int64_t)((buck) < DTRACE_QUANTIZE_ZEROBUCKET ?                 \ 
 611         -(1LL << (DTRACE_QUANTIZE_ZEROBUCKET - 1 - (buck))) :           \ 
 612         (buck) == DTRACE_QUANTIZE_ZEROBUCKET ? 0 :                      \ 
 613         1LL << ((buck) - DTRACE_QUANTIZE_ZEROBUCKET - 1)) 
 615 #define DTRACE_LQUANTIZE_STEPSHIFT              48 
 616 #define DTRACE_LQUANTIZE_STEPMASK               ((uint64_t)UINT16_MAX << 48) 
 617 #define DTRACE_LQUANTIZE_LEVELSHIFT             32 
 618 #define DTRACE_LQUANTIZE_LEVELMASK              ((uint64_t)UINT16_MAX << 32) 
 619 #define DTRACE_LQUANTIZE_BASESHIFT              0 
 620 #define DTRACE_LQUANTIZE_BASEMASK               UINT32_MAX 
 622 #define DTRACE_LQUANTIZE_STEP(x)                \ 
 623         (uint16_t)(((x) & DTRACE_LQUANTIZE_STEPMASK) >> \ 
 624         DTRACE_LQUANTIZE_STEPSHIFT) 
 626 #define DTRACE_LQUANTIZE_LEVELS(x)              \ 
 627         (uint16_t)(((x) & DTRACE_LQUANTIZE_LEVELMASK) >> \ 
 628         DTRACE_LQUANTIZE_LEVELSHIFT) 
 630 #define DTRACE_LQUANTIZE_BASE(x)                \ 
 631         (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \ 
 632         DTRACE_LQUANTIZE_BASESHIFT) 
 634 #define  DTRACE_LLQUANTIZE_FACTORSHIFT          48 
 635 #define  DTRACE_LLQUANTIZE_FACTORMASK           ((uint64_t)UINT16_MAX << 48) 
 636 #define  DTRACE_LLQUANTIZE_LOWSHIFT             32 
 637 #define  DTRACE_LLQUANTIZE_LOWMASK              ((uint64_t)UINT16_MAX << 32) 
 638 #define  DTRACE_LLQUANTIZE_HIGHSHIFT            16 
 639 #define  DTRACE_LLQUANTIZE_HIGHMASK             ((uint64_t)UINT16_MAX << 16) 
 640 #define  DTRACE_LLQUANTIZE_NSTEPSHIFT           0 
 641 #define  DTRACE_LLQUANTIZE_NSTEPMASK            UINT16_MAX 
 643 #define  DTRACE_LLQUANTIZE_FACTOR(x)   \ 
 644         (uint16_t)(((x) & DTRACE_LLQUANTIZE_FACTORMASK) >> \ 
 645         DTRACE_LLQUANTIZE_FACTORSHIFT) 
 647 #define  DTRACE_LLQUANTIZE_LOW(x)    \ 
 648         (uint16_t)(((x) & DTRACE_LLQUANTIZE_LOWMASK) >> \ 
 649         DTRACE_LLQUANTIZE_LOWSHIFT) 
 651 #define  DTRACE_LLQUANTIZE_HIGH(x)   \ 
 652         (uint16_t)(((x) & DTRACE_LLQUANTIZE_HIGHMASK) >> \ 
 653         DTRACE_LLQUANTIZE_HIGHSHIFT) 
 655 #define  DTRACE_LLQUANTIZE_NSTEP(x)    \ 
 656         (uint16_t)(((x) & DTRACE_LLQUANTIZE_NSTEPMASK) >> \ 
 657         DTRACE_LLQUANTIZE_NSTEPSHIFT) 
 659 #define DTRACE_USTACK_NFRAMES(x)        (uint32_t)((x) & UINT32_MAX) 
 660 #define DTRACE_USTACK_STRSIZE(x)        (uint32_t)((x) >> 32) 
 661 #define DTRACE_USTACK_ARG(x, y)         \ 
 662         ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) 
 664 #if !defined(__APPLE__) 
 667 #ifndef _LITTLE_ENDIAN 
 668 #define DTRACE_PTR(type, name)  uint32_t name##pad; type *name 
 670 #define DTRACE_PTR(type, name)  type *name; uint32_t name##pad 
 673 #define DTRACE_PTR(type, name)  type *name 
 679 #define DTRACE_PTR(type, name)  user_addr_t name 
 681 #define DTRACE_PTR(type, name)  type *name 
 684 #endif /* __APPLE__ */ 
 687  * DTrace Object Format (DOF) 
 689  * DTrace programs can be persistently encoded in the DOF format so that they 
 690  * may be embedded in other programs (for example, in an ELF file) or in the 
 691  * dtrace driver configuration file for use in anonymous tracing.  The DOF 
 692  * format is versioned and extensible so that it can be revised and so that 
 693  * internal data structures can be modified or extended compatibly.  All DOF 
 694  * structures use fixed-size types, so the 32-bit and 64-bit representations 
 695  * are identical and consumers can use either data model transparently. 
 697  * The file layout is structured as follows: 
 699  * +---------------+-------------------+----- ... ----+---- ... ------+ 
 700  * |   dof_hdr_t   |  dof_sec_t[ ... ] |   loadable   | non-loadable  | 
 701  * | (file header) | (section headers) | section data | section data  | 
 702  * +---------------+-------------------+----- ... ----+---- ... ------+ 
 703  * |<------------ dof_hdr.dofh_loadsz --------------->|               | 
 704  * |<------------ dof_hdr.dofh_filesz ------------------------------->| 
 706  * The file header stores meta-data including a magic number, data model for 
 707  * the instrumentation, data encoding, and properties of the DIF code within. 
 708  * The header describes its own size and the size of the section headers.  By 
 709  * convention, an array of section headers follows the file header, and then 
 710  * the data for all loadable sections and unloadable sections.  This permits 
 711  * consumer code to easily download the headers and all loadable data into the 
 712  * DTrace driver in one contiguous chunk, omitting other extraneous sections. 
 714  * The section headers describe the size, offset, alignment, and section type 
 715  * for each section.  Sections are described using a set of #defines that tell 
 716  * the consumer what kind of data is expected.  Sections can contain links to 
 717  * other sections by storing a dof_secidx_t, an index into the section header 
 718  * array, inside of the section data structures.  The section header includes 
 719  * an entry size so that sections with data arrays can grow their structures. 
 721  * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which 
 722  * are represented themselves as a collection of related DOF sections.  This 
 723  * permits us to change the set of sections associated with a DIFO over time, 
 724  * and also permits us to encode DIFOs that contain different sets of sections. 
 725  * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a 
 726  * section of type DOF_SECT_DIFOHDR.  This section's data is then an array of 
 727  * dof_secidx_t's which in turn denote the sections associated with this DIFO. 
 729  * This loose coupling of the file structure (header and sections) to the 
 730  * structure of the DTrace program itself (ECB descriptions, action 
 731  * descriptions, and DIFOs) permits activities such as relocation processing 
 732  * to occur in a single pass without having to understand D program structure. 
 734  * Finally, strings are always stored in ELF-style string tables along with a 
 735  * string table section index and string table offset.  Therefore strings in 
 736  * DOF are always arbitrary-length and not bound to the current implementation. 
 739 #define DOF_ID_SIZE     16      /* total size of dofh_ident[] in bytes */ 
 741 typedef struct dof_hdr 
{ 
 742         uint8_t dofh_ident
[DOF_ID_SIZE
]; /* identification bytes (see below) */ 
 743         uint32_t dofh_flags
;            /* file attribute flags (if any) */ 
 744         uint32_t dofh_hdrsize
;          /* size of file header in bytes */ 
 745         uint32_t dofh_secsize
;          /* size of section header in bytes */ 
 746         uint32_t dofh_secnum
;           /* number of section headers */ 
 747         uint64_t dofh_secoff
;           /* file offset of section headers */ 
 748         uint64_t dofh_loadsz
;           /* file size of loadable portion */ 
 749         uint64_t dofh_filesz
;           /* file size of entire DOF file */ 
 750         uint64_t dofh_pad
;              /* reserved for future use */ 
 753 #define DOF_ID_MAG0     0       /* first byte of magic number */ 
 754 #define DOF_ID_MAG1     1       /* second byte of magic number */ 
 755 #define DOF_ID_MAG2     2       /* third byte of magic number */ 
 756 #define DOF_ID_MAG3     3       /* fourth byte of magic number */ 
 757 #define DOF_ID_MODEL    4       /* DOF data model (see below) */ 
 758 #define DOF_ID_ENCODING 5       /* DOF data encoding (see below) */ 
 759 #define DOF_ID_VERSION  6       /* DOF file format major version (see below) */ 
 760 #define DOF_ID_DIFVERS  7       /* DIF instruction set version */ 
 761 #define DOF_ID_DIFIREG  8       /* DIF integer registers used by compiler */ 
 762 #define DOF_ID_DIFTREG  9       /* DIF tuple registers used by compiler */ 
 763 #define DOF_ID_PAD      10      /* start of padding bytes (all zeroes) */ 
 765 #define DOF_MAG_MAG0    0x7F    /* DOF_ID_MAG[0-3] */ 
 766 #define DOF_MAG_MAG1    'D' 
 767 #define DOF_MAG_MAG2    'O' 
 768 #define DOF_MAG_MAG3    'F' 
 770 #define DOF_MAG_STRING  "\177DOF" 
 771 #define DOF_MAG_STRLEN  4 
 773 #define DOF_MODEL_NONE  0       /* DOF_ID_MODEL */ 
 774 #define DOF_MODEL_ILP32 1 
 775 #define DOF_MODEL_LP64  2 
 778 #define DOF_MODEL_NATIVE        DOF_MODEL_LP64 
 780 #define DOF_MODEL_NATIVE        DOF_MODEL_ILP32 
 783 #define DOF_ENCODE_NONE 0       /* DOF_ID_ENCODING */ 
 784 #define DOF_ENCODE_LSB  1 
 785 #define DOF_ENCODE_MSB  2 
 788 #define DOF_ENCODE_NATIVE       DOF_ENCODE_MSB 
 790 #define DOF_ENCODE_NATIVE       DOF_ENCODE_LSB 
 793 #define DOF_VERSION_1   1       /* DOF version 1: Solaris 10 FCS */ 
 794 #define DOF_VERSION_2   2       /* DOF version 2: Solaris Express 6/06 */ 
 795 #if !defined(__APPLE__) 
 796 #define DOF_VERSION     DOF_VERSION_2   /* Latest DOF version */ 
 798 #define DOF_VERSION_3   3       /* DOF version 3: Minimum version for Leopard */ 
 799 #define DOF_VERSION     DOF_VERSION_3   /* Latest DOF version */ 
 800 #endif /* __APPLE__ */ 
 802 #define DOF_FL_VALID    0       /* mask of all valid dofh_flags bits */ 
 804 typedef uint32_t dof_secidx_t
;  /* section header table index type */ 
 805 typedef uint32_t dof_stridx_t
;  /* string table index type */ 
 807 #define DOF_SECIDX_NONE (-1U)   /* null value for section indices */ 
 808 #define DOF_STRIDX_NONE (-1U)   /* null value for string indices */ 
 810 typedef struct dof_sec 
{ 
 811         uint32_t dofs_type
;     /* section type (see below) */ 
 812         uint32_t dofs_align
;    /* section data memory alignment */ 
 813         uint32_t dofs_flags
;    /* section flags (if any) */ 
 814         uint32_t dofs_entsize
;  /* size of section entry (if table) */ 
 815         uint64_t dofs_offset
;   /* offset of section data within file */ 
 816         uint64_t dofs_size
;     /* size of section data in bytes */ 
 819 #define DOF_SECT_NONE           0       /* null section */ 
 820 #define DOF_SECT_COMMENTS       1       /* compiler comments */ 
 821 #define DOF_SECT_SOURCE         2       /* D program source code */ 
 822 #define DOF_SECT_ECBDESC        3       /* dof_ecbdesc_t */ 
 823 #define DOF_SECT_PROBEDESC      4       /* dof_probedesc_t */ 
 824 #define DOF_SECT_ACTDESC        5       /* dof_actdesc_t array */ 
 825 #define DOF_SECT_DIFOHDR        6       /* dof_difohdr_t (variable length) */ 
 826 #define DOF_SECT_DIF            7       /* uint32_t array of byte code */ 
 827 #define DOF_SECT_STRTAB         8       /* string table */ 
 828 #define DOF_SECT_VARTAB         9       /* dtrace_difv_t array */ 
 829 #define DOF_SECT_RELTAB         10      /* dof_relodesc_t array */ 
 830 #define DOF_SECT_TYPTAB         11      /* dtrace_diftype_t array */ 
 831 #define DOF_SECT_URELHDR        12      /* dof_relohdr_t (user relocations) */ 
 832 #define DOF_SECT_KRELHDR        13      /* dof_relohdr_t (kernel relocations) */ 
 833 #define DOF_SECT_OPTDESC        14      /* dof_optdesc_t array */ 
 834 #define DOF_SECT_PROVIDER       15      /* dof_provider_t */ 
 835 #define DOF_SECT_PROBES         16      /* dof_probe_t array */ 
 836 #define DOF_SECT_PRARGS         17      /* uint8_t array (probe arg mappings) */ 
 837 #define DOF_SECT_PROFFS         18      /* uint32_t array (probe arg offsets) */ 
 838 #define DOF_SECT_INTTAB         19      /* uint64_t array */ 
 839 #define DOF_SECT_UTSNAME        20      /* struct utsname */ 
 840 #define DOF_SECT_XLTAB          21      /* dof_xlref_t array */ 
 841 #define DOF_SECT_XLMEMBERS      22      /* dof_xlmember_t array */ 
 842 #define DOF_SECT_XLIMPORT       23      /* dof_xlator_t */ 
 843 #define DOF_SECT_XLEXPORT       24      /* dof_xlator_t */ 
 844 #define DOF_SECT_PREXPORT       25      /* dof_secidx_t array (exported objs) */ 
 845 #define DOF_SECT_PRENOFFS       26      /* uint32_t array (enabled offsets) */ 
 847 #define DOF_SECF_LOAD           1       /* section should be loaded */ 
 849 typedef struct dof_ecbdesc 
{ 
 850         dof_secidx_t dofe_probes
;       /* link to DOF_SECT_PROBEDESC */ 
 851         dof_secidx_t dofe_pred
;         /* link to DOF_SECT_DIFOHDR */ 
 852         dof_secidx_t dofe_actions
;      /* link to DOF_SECT_ACTDESC */ 
 853         uint32_t dofe_pad
;              /* reserved for future use */ 
 854         uint64_t dofe_uarg
;             /* user-supplied library argument */ 
 857 typedef struct dof_probedesc 
{ 
 858         dof_secidx_t dofp_strtab
;       /* link to DOF_SECT_STRTAB section */ 
 859         dof_stridx_t dofp_provider
;     /* provider string */ 
 860         dof_stridx_t dofp_mod
;          /* module string */ 
 861         dof_stridx_t dofp_func
;         /* function string */ 
 862         dof_stridx_t dofp_name
;         /* name string */ 
 863         uint32_t dofp_id
;               /* probe identifier (or zero) */ 
 866 typedef struct dof_actdesc 
{ 
 867         dof_secidx_t dofa_difo
;         /* link to DOF_SECT_DIFOHDR */ 
 868         dof_secidx_t dofa_strtab
;       /* link to DOF_SECT_STRTAB section */ 
 869         uint32_t dofa_kind
;             /* action kind (DTRACEACT_* constant) */ 
 870         uint32_t dofa_ntuple
;           /* number of subsequent tuple actions */ 
 871         uint64_t dofa_arg
;              /* kind-specific argument */ 
 872         uint64_t dofa_uarg
;             /* user-supplied argument */ 
 875 typedef struct dof_difohdr 
{ 
 876         dtrace_diftype_t dofd_rtype
;    /* return type for this fragment */ 
 877         dof_secidx_t dofd_links
[1];     /* variable length array of indices */ 
 880 typedef struct dof_relohdr 
{ 
 881         dof_secidx_t dofr_strtab
;       /* link to DOF_SECT_STRTAB for names */ 
 882         dof_secidx_t dofr_relsec
;       /* link to DOF_SECT_RELTAB for relos */ 
 883         dof_secidx_t dofr_tgtsec
;       /* link to section we are relocating */ 
 886 typedef struct dof_relodesc 
{ 
 887         dof_stridx_t dofr_name
;         /* string name of relocation symbol */ 
 888         uint32_t dofr_type
;             /* relo type (DOF_RELO_* constant) */ 
 889         uint64_t dofr_offset
;           /* byte offset for relocation */ 
 890         uint64_t dofr_data
;             /* additional type-specific data */ 
 893 #define DOF_RELO_NONE   0               /* empty relocation entry */ 
 894 #define DOF_RELO_SETX   1               /* relocate setx value */ 
 896 typedef struct dof_optdesc 
{ 
 897         uint32_t dofo_option
;           /* option identifier */ 
 898         dof_secidx_t dofo_strtab
;       /* string table, if string option */ 
 899         uint64_t dofo_value
;            /* option value or string index */ 
 902 typedef uint32_t dof_attr_t
;            /* encoded stability attributes */ 
 904 #define DOF_ATTR(n, d, c)       (((n) << 24) | ((d) << 16) | ((c) << 8)) 
 905 #define DOF_ATTR_NAME(a)        (((a) >> 24) & 0xff) 
 906 #define DOF_ATTR_DATA(a)        (((a) >> 16) & 0xff) 
 907 #define DOF_ATTR_CLASS(a)       (((a) >>  8) & 0xff) 
 909 typedef struct dof_provider 
{ 
 910         dof_secidx_t dofpv_strtab
;      /* link to DOF_SECT_STRTAB section */ 
 911         dof_secidx_t dofpv_probes
;      /* link to DOF_SECT_PROBES section */ 
 912         dof_secidx_t dofpv_prargs
;      /* link to DOF_SECT_PRARGS section */ 
 913         dof_secidx_t dofpv_proffs
;      /* link to DOF_SECT_PROFFS section */ 
 914         dof_stridx_t dofpv_name
;        /* provider name string */ 
 915         dof_attr_t dofpv_provattr
;      /* provider attributes */ 
 916         dof_attr_t dofpv_modattr
;       /* module attributes */ 
 917         dof_attr_t dofpv_funcattr
;      /* function attributes */ 
 918         dof_attr_t dofpv_nameattr
;      /* name attributes */ 
 919         dof_attr_t dofpv_argsattr
;      /* args attributes */ 
 920         dof_secidx_t dofpv_prenoffs
;    /* link to DOF_SECT_PRENOFFS section */ 
 923 typedef struct dof_probe 
{ 
 924         uint64_t dofpr_addr
;            /* probe base address or offset */ 
 925         dof_stridx_t dofpr_func
;        /* probe function string */ 
 926         dof_stridx_t dofpr_name
;        /* probe name string */ 
 927         dof_stridx_t dofpr_nargv
;       /* native argument type strings */ 
 928         dof_stridx_t dofpr_xargv
;       /* translated argument type strings */ 
 929         uint32_t dofpr_argidx
;          /* index of first argument mapping */ 
 930         uint32_t dofpr_offidx
;          /* index of first offset entry */ 
 931         uint8_t dofpr_nargc
;            /* native argument count */ 
 932         uint8_t dofpr_xargc
;            /* translated argument count */ 
 933         uint16_t dofpr_noffs
;           /* number of offset entries for probe */ 
 934         uint32_t dofpr_enoffidx
;        /* index of first is-enabled offset */ 
 935         uint16_t dofpr_nenoffs
;         /* number of is-enabled offsets */ 
 936         uint16_t dofpr_pad1
;            /* reserved for future use */ 
 937         uint32_t dofpr_pad2
;            /* reserved for future use */ 
 940 typedef struct dof_xlator 
{ 
 941         dof_secidx_t dofxl_members
;     /* link to DOF_SECT_XLMEMBERS section */ 
 942         dof_secidx_t dofxl_strtab
;      /* link to DOF_SECT_STRTAB section */ 
 943         dof_stridx_t dofxl_argv
;        /* input parameter type strings */ 
 944         uint32_t dofxl_argc
;            /* input parameter list length */ 
 945         dof_stridx_t dofxl_type
;        /* output type string name */ 
 946         dof_attr_t dofxl_attr
;          /* output stability attributes */ 
 949 typedef struct dof_xlmember 
{ 
 950         dof_secidx_t dofxm_difo
;        /* member link to DOF_SECT_DIFOHDR */ 
 951         dof_stridx_t dofxm_name
;        /* member name */ 
 952         dtrace_diftype_t dofxm_type
;    /* member type */ 
 955 typedef struct dof_xlref 
{ 
 956         dof_secidx_t dofxr_xlator
;      /* link to DOF_SECT_XLATORS section */ 
 957         uint32_t dofxr_member
;          /* index of referenced dof_xlmember */ 
 958         uint32_t dofxr_argn
;            /* index of argument for DIF_OP_XLARG */ 
 962  * DTrace Intermediate Format Object (DIFO) 
 964  * A DIFO is used to store the compiled DIF for a D expression, its return 
 965  * type, and its string and variable tables.  The string table is a single 
 966  * buffer of character data into which sets instructions and variable 
 967  * references can reference strings using a byte offset.  The variable table 
 968  * is an array of dtrace_difv_t structures that describe the name and type of 
 969  * each variable and the id used in the DIF code.  This structure is described 
 970  * above in the DIF section of this header file.  The DIFO is used at both 
 971  * user-level (in the library) and in the kernel, but the structure is never 
 972  * passed between the two: the DOF structures form the only interface.  As a 
 973  * result, the definition can change depending on the presence of _KERNEL. 
 975 typedef struct dtrace_difo 
{ 
 976         dif_instr_t 
*dtdo_buf
;          /* instruction buffer */ 
 977         uint64_t *dtdo_inttab
;          /* integer table (optional) */ 
 978         char *dtdo_strtab
;              /* string table (optional) */ 
 979         dtrace_difv_t 
*dtdo_vartab
;     /* variable table (optional) */ 
 980         uint_t dtdo_len
;                /* length of instruction buffer */ 
 981         uint_t dtdo_intlen
;             /* length of integer table */ 
 982         uint_t dtdo_strlen
;             /* length of string table */ 
 983         uint_t dtdo_varlen
;             /* length of variable table */ 
 984         dtrace_diftype_t dtdo_rtype
;    /* return type */ 
 985         uint_t dtdo_refcnt
;             /* owner reference count */ 
 986         uint_t dtdo_destructive
;        /* invokes destructive subroutines */ 
 988         dof_relodesc_t 
*dtdo_kreltab
;   /* kernel relocations */ 
 989         dof_relodesc_t 
*dtdo_ureltab
;   /* user relocations */ 
 990         struct dt_node 
**dtdo_xlmtab
;   /* translator references */ 
 991         uint_t dtdo_krelen
;             /* length of krelo table */ 
 992         uint_t dtdo_urelen
;             /* length of urelo table */ 
 993         uint_t dtdo_xlmlen
;             /* length of translator table */ 
 998  * DTrace Enabling Description Structures 
1000  * When DTrace is tracking the description of a DTrace enabling entity (probe, 
1001  * predicate, action, ECB, record, etc.), it does so in a description 
1002  * structure.  These structures all end in "desc", and are used at both 
1003  * user-level and in the kernel -- but (with the exception of 
1004  * dtrace_probedesc_t) they are never passed between them.  Typically, 
1005  * user-level will use the description structures when assembling an enabling. 
1006  * It will then distill those description structures into a DOF object (see 
1007  * above), and send it into the kernel.  The kernel will again use the 
1008  * description structures to create a description of the enabling as it reads 
1009  * the DOF.  When the description is complete, the enabling will be actually 
1010  * created -- turning it into the structures that represent the enabling 
1011  * instead of merely describing it.  Not surprisingly, the description 
1012  * structures bear a strong resemblance to the DOF structures that act as their 
1015 struct dtrace_predicate
; 
1017 typedef struct dtrace_probedesc 
{ 
1018         dtrace_id_t dtpd_id
;                    /* probe identifier */ 
1019         char dtpd_provider
[DTRACE_PROVNAMELEN
]; /* probe provider name */ 
1020         char dtpd_mod
[DTRACE_MODNAMELEN
];       /* probe module name */ 
1021         char dtpd_func
[DTRACE_FUNCNAMELEN
];     /* probe function name */ 
1022         char dtpd_name
[DTRACE_NAMELEN
];         /* probe name */ 
1023 } dtrace_probedesc_t
; 
1025 typedef struct dtrace_repldesc 
{ 
1026         dtrace_probedesc_t dtrpd_match
;         /* probe descr. to match */ 
1027         dtrace_probedesc_t dtrpd_create
;        /* probe descr. to create */ 
1028 } dtrace_repldesc_t
; 
1030 typedef struct dtrace_preddesc 
{ 
1031         dtrace_difo_t 
*dtpdd_difo
;              /* pointer to DIF object */ 
1032         struct dtrace_predicate 
*dtpdd_predicate
; /* pointer to predicate */ 
1033 } dtrace_preddesc_t
; 
1035 typedef struct dtrace_actdesc 
{ 
1036         dtrace_difo_t 
*dtad_difo
;               /* pointer to DIF object */ 
1037         struct dtrace_actdesc 
*dtad_next
;       /* next action */ 
1038         dtrace_actkind_t dtad_kind
;             /* kind of action */ 
1039         uint32_t dtad_ntuple
;                   /* number in tuple */ 
1040         uint64_t dtad_arg
;                      /* action argument */ 
1041         uint64_t dtad_uarg
;                     /* user argument */ 
1042         int dtad_refcnt
;                        /* reference count */ 
1046 typedef struct dtrace_ecbdesc 
{ 
1047         dtrace_actdesc_t 
*dted_action
;          /* action description(s) */ 
1048         dtrace_preddesc_t dted_pred
;            /* predicate description */ 
1049         dtrace_probedesc_t dted_probe
;          /* probe description */ 
1050         uint64_t dted_uarg
;                     /* library argument */ 
1051         int dted_refcnt
;                        /* reference count */ 
1052         uint64_t dted_probegen
;                 /* matched probe generation */ 
1056  * APPLE NOTE: The kernel always rebuild dtrace_ecbdesc structures 
1057  * coming from userspace, so there is no dted_probegen manipulation risk 
1061  * DTrace Metadata Description Structures 
1063  * DTrace separates the trace data stream from the metadata stream.  The only 
1064  * metadata tokens placed in the data stream are the dtrace_rechdr_t (EPID + 
1065  * timestamp) or (in the case of aggregations) aggregation identifiers.  To 
1066  * determine the structure of the data, DTrace consumers pass the token to the 
1067  * kernel, and receive in return a corresponding description of the enabled 
1068  * probe (via the dtrace_eprobedesc structure) or the aggregation (via the 
1069  * dtrace_aggdesc structure).  Both of these structures are expressed in terms 
1070  * of record descriptions (via the dtrace_recdesc structure) that describe the 
1071  * exact structure of the data.  Some record descriptions may also contain a 
1072  * format identifier; this additional bit of metadata can be retrieved from the 
1073  * kernel, for which a format description is returned via the dtrace_fmtdesc 
1074  * structure.  Note that all four of these structures must be bitness-neutral 
1075  * to allow for a 32-bit DTrace consumer on a 64-bit kernel. 
1077 typedef struct dtrace_recdesc 
{ 
1078         dtrace_actkind_t dtrd_action
;           /* kind of action */ 
1079         uint32_t dtrd_size
;                     /* size of record */ 
1080         uint32_t dtrd_offset
;                   /* offset in ECB's data */ 
1081         uint16_t dtrd_alignment
;                /* required alignment */ 
1082         uint16_t dtrd_format
;                   /* format, if any */ 
1083         uint64_t dtrd_arg
;                      /* action argument */ 
1084         uint64_t dtrd_uarg
;                     /* user argument */ 
1087 typedef struct dtrace_eprobedesc 
{ 
1088         dtrace_epid_t dtepd_epid
;               /* enabled probe ID */ 
1089         dtrace_id_t dtepd_probeid
;              /* probe ID */ 
1090         uint64_t dtepd_uarg
;                    /* library argument */ 
1091         uint32_t dtepd_size
;                    /* total size */ 
1092         int dtepd_nrecs
;                        /* number of records */ 
1093         dtrace_recdesc_t dtepd_rec
[1];          /* records themselves */ 
1094 } dtrace_eprobedesc_t
; 
1096 typedef struct dtrace_aggdesc 
{ 
1097         DTRACE_PTR(char, dtagd_name
);           /* not filled in by kernel */ 
1098         dtrace_aggvarid_t dtagd_varid
;          /* not filled in by kernel */ 
1099         int dtagd_flags
;                        /* not filled in by kernel */ 
1100         dtrace_aggid_t dtagd_id
;                /* aggregation ID */ 
1101         dtrace_epid_t dtagd_epid
;               /* enabled probe ID */ 
1102         uint32_t dtagd_size
;                    /* size in bytes */ 
1103         int dtagd_nrecs
;                        /* number of records */ 
1104         uint32_t dtagd_pad
;                     /* explicit padding */ 
1105         dtrace_recdesc_t dtagd_rec
[1];          /* record descriptions */ 
1108 typedef struct dtrace_fmtdesc 
{ 
1109         DTRACE_PTR(char, dtfd_string
);          /* format string */ 
1110         int dtfd_length
;                        /* length of format string */ 
1111         uint16_t dtfd_format
;                   /* format identifier */ 
1114 #define DTRACE_SIZEOF_EPROBEDESC(desc)                          \ 
1115         (sizeof (dtrace_eprobedesc_t) + ((desc)->dtepd_nrecs ?  \ 
1116         (((desc)->dtepd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 
1118 #define DTRACE_SIZEOF_AGGDESC(desc)                             \ 
1119         (sizeof (dtrace_aggdesc_t) + ((desc)->dtagd_nrecs ?     \ 
1120         (((desc)->dtagd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) 
1123  * DTrace Option Interface 
1125  * Run-time DTrace options are set and retrieved via DOF_SECT_OPTDESC sections 
1126  * in a DOF image.  The dof_optdesc structure contains an option identifier and 
1127  * an option value.  The valid option identifiers are found below; the mapping 
1128  * between option identifiers and option identifying strings is maintained at 
1129  * user-level.  Note that the value of DTRACEOPT_UNSET is such that all of the 
1130  * following are potentially valid option values:  all positive integers, zero 
1131  * and negative one.  Some options (notably "bufpolicy" and "bufresize") take 
1132  * predefined tokens as their values; these are defined with 
1133  * DTRACEOPT_{option}_{token}. 
1135 #define DTRACEOPT_BUFSIZE       0       /* buffer size */ 
1136 #define DTRACEOPT_BUFPOLICY     1       /* buffer policy */ 
1137 #define DTRACEOPT_DYNVARSIZE    2       /* dynamic variable size */ 
1138 #define DTRACEOPT_AGGSIZE       3       /* aggregation size */ 
1139 #define DTRACEOPT_SPECSIZE      4       /* speculation size */ 
1140 #define DTRACEOPT_NSPEC         5       /* number of speculations */ 
1141 #define DTRACEOPT_STRSIZE       6       /* string size */ 
1142 #define DTRACEOPT_CLEANRATE     7       /* dynvar cleaning rate */ 
1143 #define DTRACEOPT_CPU           8       /* CPU to trace */ 
1144 #define DTRACEOPT_BUFRESIZE     9       /* buffer resizing policy */ 
1145 #define DTRACEOPT_GRABANON      10      /* grab anonymous state, if any */ 
1146 #define DTRACEOPT_FLOWINDENT    11      /* indent function entry/return */ 
1147 #define DTRACEOPT_QUIET         12      /* only output explicitly traced data */ 
1148 #define DTRACEOPT_STACKFRAMES   13      /* number of stack frames */ 
1149 #define DTRACEOPT_USTACKFRAMES  14      /* number of user stack frames */ 
1150 #define DTRACEOPT_AGGRATE       15      /* aggregation snapshot rate */ 
1151 #define DTRACEOPT_SWITCHRATE    16      /* buffer switching rate */ 
1152 #define DTRACEOPT_STATUSRATE    17      /* status rate */ 
1153 #define DTRACEOPT_DESTRUCTIVE   18      /* destructive actions allowed */ 
1154 #define DTRACEOPT_STACKINDENT   19      /* output indent for stack traces */ 
1155 #define DTRACEOPT_RAWBYTES      20      /* always print bytes in raw form */ 
1156 #define DTRACEOPT_JSTACKFRAMES  21      /* number of jstack() frames */ 
1157 #define DTRACEOPT_JSTACKSTRSIZE 22      /* size of jstack() string table */ 
1158 #define DTRACEOPT_AGGSORTKEY    23      /* sort aggregations by key */ 
1159 #define DTRACEOPT_AGGSORTREV    24      /* reverse-sort aggregations */ 
1160 #define DTRACEOPT_AGGSORTPOS    25      /* agg. position to sort on */ 
1161 #define DTRACEOPT_AGGSORTKEYPOS 26      /* agg. key position to sort on */ 
1162 #define DTRACEOPT_AGGHIST       27      /* histogram aggregation output */ 
1163 #define DTRACEOPT_AGGPACK       28      /* packed aggregation output */ 
1164 #define DTRACEOPT_AGGZOOM       29      /* zoomed aggregation scaling */ 
1165 #define DTRACEOPT_TEMPORAL      30      /* temporally ordered output */ 
1166 #if !defined(__APPLE__) 
1167 #define DTRACEOPT_MAX           31      /* number of options */ 
1169 #define DTRACEOPT_STACKSYMBOLS  31      /* clear to prevent stack symbolication */ 
1170 #define DTRACEOPT_BUFLIMIT      32      /* buffer signaling limit in % of the size */ 
1171 #define DTRACEOPT_MAX           33      /* number of options */ 
1172 #endif /* __APPLE__ */ 
1174 #define DTRACEOPT_UNSET         (dtrace_optval_t)-2     /* unset option */ 
1176 #define DTRACEOPT_BUFPOLICY_RING        0       /* ring buffer */ 
1177 #define DTRACEOPT_BUFPOLICY_FILL        1       /* fill buffer, then stop */ 
1178 #define DTRACEOPT_BUFPOLICY_SWITCH      2       /* switch buffers */ 
1180 #define DTRACEOPT_BUFRESIZE_AUTO        0       /* automatic resizing */ 
1181 #define DTRACEOPT_BUFRESIZE_MANUAL      1       /* manual resizing */ 
1184  * DTrace Buffer Interface 
1186  * In order to get a snapshot of the principal or aggregation buffer, 
1187  * user-level passes a buffer description to the kernel with the dtrace_bufdesc 
1188  * structure.  This describes which CPU user-level is interested in, and 
1189  * where user-level wishes the kernel to snapshot the buffer to (the 
1190  * dtbd_data field).  The kernel uses the same structure to pass back some 
1191  * information regarding the buffer:  the size of data actually copied out, the 
1192  * number of drops, the number of errors, the offset of the oldest record, 
1193  * and the time of the snapshot. 
1195  * If the buffer policy is a "switch" policy, taking a snapshot of the 
1196  * principal buffer has the additional effect of switching the active and 
1197  * inactive buffers.  Taking a snapshot of the aggregation buffer _always_ has 
1198  * the additional effect of switching the active and inactive buffers. 
1200 typedef struct dtrace_bufdesc 
{ 
1201         uint64_t dtbd_size
;                     /* size of buffer */ 
1202         uint32_t dtbd_cpu
;                      /* CPU or DTRACE_CPUALL */ 
1203         uint32_t dtbd_errors
;                   /* number of errors */ 
1204         uint64_t dtbd_drops
;                    /* number of drops */ 
1205         DTRACE_PTR(char, dtbd_data
);            /* data */ 
1206         uint64_t dtbd_oldest
;                   /* offset of oldest record */ 
1207         uint64_t dtbd_timestamp
;                /* hrtime of snapshot */ 
1211  * Each record in the buffer (dtbd_data) begins with a header that includes 
1212  * the epid and a timestamp.  The timestamp is split into two 4-byte parts 
1213  * so that we do not require 8-byte alignment. 
1215 typedef struct dtrace_rechdr 
{ 
1216         dtrace_epid_t dtrh_epid
;                /* enabled probe id */ 
1217         uint32_t dtrh_timestamp_hi
;             /* high bits of hrtime_t */ 
1218         uint32_t dtrh_timestamp_lo
;             /* low bits of hrtime_t */ 
1221 #define DTRACE_RECORD_LOAD_TIMESTAMP(dtrh)                      \ 
1222         ((dtrh)->dtrh_timestamp_lo +                            \ 
1223         ((uint64_t)(dtrh)->dtrh_timestamp_hi << 32)) 
1225 #define DTRACE_RECORD_STORE_TIMESTAMP(dtrh, hrtime) {           \ 
1226         (dtrh)->dtrh_timestamp_lo = (uint32_t)hrtime;           \ 
1227         (dtrh)->dtrh_timestamp_hi = hrtime >> 32;               \ 
1233  * The status of DTrace is relayed via the dtrace_status structure.  This 
1234  * structure contains members to count drops other than the capacity drops 
1235  * available via the buffer interface (see above).  This consists of dynamic 
1236  * drops (including capacity dynamic drops, rinsing drops and dirty drops), and 
1237  * speculative drops (including capacity speculative drops, drops due to busy 
1238  * speculative buffers and drops due to unavailable speculative buffers). 
1239  * Additionally, the status structure contains a field to indicate the number 
1240  * of "fill"-policy buffers have been filled and a boolean field to indicate 
1241  * that exit() has been called.  If the dtst_exiting field is non-zero, no 
1242  * further data will be generated until tracing is stopped (at which time any 
1243  * enablings of the END action will be processed); if user-level sees that 
1244  * this field is non-zero, tracing should be stopped as soon as possible. 
1246 typedef struct dtrace_status 
{ 
1247         uint64_t dtst_dyndrops
;                 /* dynamic drops */ 
1248         uint64_t dtst_dyndrops_rinsing
;         /* dyn drops due to rinsing */ 
1249         uint64_t dtst_dyndrops_dirty
;           /* dyn drops due to dirty */ 
1250         uint64_t dtst_specdrops
;                /* speculative drops */ 
1251         uint64_t dtst_specdrops_busy
;           /* spec drops due to busy */ 
1252         uint64_t dtst_specdrops_unavail
;        /* spec drops due to unavail */ 
1253         uint64_t dtst_errors
;                   /* total errors */ 
1254         uint64_t dtst_filled
;                   /* number of filled bufs */ 
1255         uint64_t dtst_stkstroverflows
;          /* stack string tab overflows */ 
1256         uint64_t dtst_dblerrors
;                /* errors in ERROR probes */ 
1257         char dtst_killed
;                       /* non-zero if killed */ 
1258         char dtst_exiting
;                      /* non-zero if exit() called */ 
1259         char dtst_pad
[6];                       /* pad out to 64-bit align */ 
1263  * DTrace Configuration 
1265  * User-level may need to understand some elements of the kernel DTrace 
1266  * configuration in order to generate correct DIF.  This information is 
1267  * conveyed via the dtrace_conf structure. 
1269 typedef struct dtrace_conf 
{ 
1270         uint_t dtc_difversion
;                  /* supported DIF version */ 
1271         uint_t dtc_difintregs
;                  /* # of DIF integer registers */ 
1272         uint_t dtc_diftupregs
;                  /* # of DIF tuple registers */ 
1273         uint_t dtc_ctfmodel
;                    /* CTF data model */ 
1274         uint_t dtc_pad
[8];                      /* reserved for future use */ 
1280  * The constants below DTRACEFLT_LIBRARY indicate probe processing faults; 
1281  * constants at or above DTRACEFLT_LIBRARY indicate faults in probe 
1282  * postprocessing at user-level.  Probe processing faults induce an ERROR 
1283  * probe and are replicated in unistd.d to allow users' ERROR probes to decode 
1284  * the error condition using thse symbolic labels. 
1286 #define DTRACEFLT_UNKNOWN               0       /* Unknown fault */ 
1287 #define DTRACEFLT_BADADDR               1       /* Bad address */ 
1288 #define DTRACEFLT_BADALIGN              2       /* Bad alignment */ 
1289 #define DTRACEFLT_ILLOP                 3       /* Illegal operation */ 
1290 #define DTRACEFLT_DIVZERO               4       /* Divide-by-zero */ 
1291 #define DTRACEFLT_NOSCRATCH             5       /* Out of scratch space */ 
1292 #define DTRACEFLT_KPRIV                 6       /* Illegal kernel access */ 
1293 #define DTRACEFLT_UPRIV                 7       /* Illegal user access */ 
1294 #define DTRACEFLT_TUPOFLOW              8       /* Tuple stack overflow */ 
1295 #define DTRACEFLT_BADSTACK              9       /* Bad stack */ 
1297 #define DTRACEFLT_LIBRARY               1000    /* Library-level fault */ 
1300  * DTrace Argument Types 
1302  * Because it would waste both space and time, argument types do not reside 
1303  * with the probe.  In order to determine argument types for args[X] 
1304  * variables, the D compiler queries for argument types on a probe-by-probe 
1305  * basis.  (This optimizes for the common case that arguments are either not 
1306  * used or used in an untyped fashion.)  Typed arguments are specified with a 
1307  * string of the type name in the dtragd_native member of the argument 
1308  * description structure.  Typed arguments may be further translated to types 
1309  * of greater stability; the provider indicates such a translated argument by 
1310  * filling in the dtargd_xlate member with the string of the translated type. 
1311  * Finally, the provider may indicate which argument value a given argument 
1312  * maps to by setting the dtargd_mapping member -- allowing a single argument 
1313  * to map to multiple args[X] variables. 
1315 typedef struct dtrace_argdesc 
{ 
1316         dtrace_id_t dtargd_id
;                  /* probe identifier */ 
1317         int dtargd_ndx
;                         /* arg number (-1 iff none) */ 
1318         int dtargd_mapping
;                     /* value mapping */ 
1319         char dtargd_native
[DTRACE_ARGTYPELEN
];  /* native type name */ 
1320         char dtargd_xlate
[DTRACE_ARGTYPELEN
];   /* translated type name */ 
1324  * DTrace Stability Attributes 
1326  * Each DTrace provider advertises the name and data stability of each of its 
1327  * probe description components, as well as its architectural dependencies. 
1328  * The D compiler can query the provider attributes (dtrace_pattr_t below) in 
1329  * order to compute the properties of an input program and report them. 
1331 typedef uint8_t dtrace_stability_t
;     /* stability code (see attributes(5)) */ 
1332 typedef uint8_t dtrace_class_t
;         /* architectural dependency class */ 
1334 #define DTRACE_STABILITY_INTERNAL       0       /* private to DTrace itself */ 
1335 #define DTRACE_STABILITY_PRIVATE        1       /* private to Sun (see docs) */ 
1336 #define DTRACE_STABILITY_OBSOLETE       2       /* scheduled for removal */ 
1337 #define DTRACE_STABILITY_EXTERNAL       3       /* not controlled by Sun */ 
1338 #define DTRACE_STABILITY_UNSTABLE       4       /* new or rapidly changing */ 
1339 #define DTRACE_STABILITY_EVOLVING       5       /* less rapidly changing */ 
1340 #define DTRACE_STABILITY_STABLE         6       /* mature interface from Sun */ 
1341 #define DTRACE_STABILITY_STANDARD       7       /* industry standard */ 
1342 #define DTRACE_STABILITY_MAX            7       /* maximum valid stability */ 
1344 #define DTRACE_CLASS_UNKNOWN    0       /* unknown architectural dependency */ 
1345 #define DTRACE_CLASS_CPU        1       /* CPU-module-specific */ 
1346 #define DTRACE_CLASS_PLATFORM   2       /* platform-specific (uname -i) */ 
1347 #define DTRACE_CLASS_GROUP      3       /* hardware-group-specific (uname -m) */ 
1348 #define DTRACE_CLASS_ISA        4       /* ISA-specific (uname -p) */ 
1349 #define DTRACE_CLASS_COMMON     5       /* common to all systems */ 
1350 #define DTRACE_CLASS_MAX        5       /* maximum valid class */ 
1352 #define DTRACE_PRIV_NONE        0x0000 
1353 #define DTRACE_PRIV_KERNEL      0x0001 
1354 #define DTRACE_PRIV_USER        0x0002 
1355 #define DTRACE_PRIV_PROC        0x0004 
1356 #define DTRACE_PRIV_OWNER       0x0008 
1357 #define DTRACE_PRIV_ZONEOWNER   0x0010 
1359 #define DTRACE_PRIV_ALL \ 
1360         (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ 
1361         DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER) 
1363 typedef struct dtrace_ppriv 
{ 
1364         uint32_t dtpp_flags
;                    /* privilege flags */ 
1365         uid_t dtpp_uid
;                         /* user ID */ 
1366         zoneid_t dtpp_zoneid
;                   /* zone ID */ 
1369 typedef struct dtrace_attribute 
{ 
1370         dtrace_stability_t dtat_name
;           /* entity name stability */ 
1371         dtrace_stability_t dtat_data
;           /* entity data stability */ 
1372         dtrace_class_t dtat_class
;              /* entity data dependency */ 
1373 } dtrace_attribute_t
; 
1375 typedef struct dtrace_pattr 
{ 
1376         dtrace_attribute_t dtpa_provider
;       /* provider attributes */ 
1377         dtrace_attribute_t dtpa_mod
;            /* module attributes */ 
1378         dtrace_attribute_t dtpa_func
;           /* function attributes */ 
1379         dtrace_attribute_t dtpa_name
;           /* name attributes */ 
1380         dtrace_attribute_t dtpa_args
;           /* args[] attributes */ 
1383 typedef struct dtrace_providerdesc 
{ 
1384         char dtvd_name
[DTRACE_PROVNAMELEN
];     /* provider name */ 
1385         dtrace_pattr_t dtvd_attr
;               /* stability attributes */ 
1386         dtrace_ppriv_t dtvd_priv
;               /* privileges required */ 
1387 } dtrace_providerdesc_t
; 
1390  * DTrace Pseudodevice Interface 
1392  * DTrace is controlled through ioctl(2)'s to the in-kernel dtrace:dtrace 
1393  * pseudodevice driver.  These ioctls comprise the user-kernel interface to 
1396 #if !defined(__APPLE__) 
1397 #define DTRACEIOC               (('d' << 24) | ('t' << 16) | ('r' << 8)) 
1398 #define DTRACEIOC_PROVIDER      (DTRACEIOC | 1)         /* provider query */ 
1399 #define DTRACEIOC_PROBES        (DTRACEIOC | 2)         /* probe query */ 
1400 #define DTRACEIOC_BUFSNAP       (DTRACEIOC | 4)         /* snapshot buffer */ 
1401 #define DTRACEIOC_PROBEMATCH    (DTRACEIOC | 5)         /* match probes */ 
1402 #define DTRACEIOC_ENABLE        (DTRACEIOC | 6)         /* enable probes */ 
1403 #define DTRACEIOC_AGGSNAP       (DTRACEIOC | 7)         /* snapshot agg. */ 
1404 #define DTRACEIOC_EPROBE        (DTRACEIOC | 8)         /* get eprobe desc. */ 
1405 #define DTRACEIOC_PROBEARG      (DTRACEIOC | 9)         /* get probe arg */ 
1406 #define DTRACEIOC_CONF          (DTRACEIOC | 10)        /* get config. */ 
1407 #define DTRACEIOC_STATUS        (DTRACEIOC | 11)        /* get status */ 
1408 #define DTRACEIOC_GO            (DTRACEIOC | 12)        /* start tracing */ 
1409 #define DTRACEIOC_STOP          (DTRACEIOC | 13)        /* stop tracing */ 
1410 #define DTRACEIOC_AGGDESC       (DTRACEIOC | 15)        /* get agg. desc. */ 
1411 #define DTRACEIOC_FORMAT        (DTRACEIOC | 16)        /* get format str */ 
1412 #define DTRACEIOC_DOFGET        (DTRACEIOC | 17)        /* get DOF */ 
1413 #define DTRACEIOC_REPLICATE     (DTRACEIOC | 18)        /* replicate enab */ 
1415 /* coding this as IOC_VOID allows this driver to handle its own copyin/copuout */ 
1416 #define DTRACEIOC               _IO('d',0) 
1417 #define DTRACEIOC_PROVIDER      (DTRACEIOC | 1)         /* provider query */ 
1418 #define DTRACEIOC_PROBES        (DTRACEIOC | 2)         /* probe query */ 
1419 #define DTRACEIOC_BUFSNAP       (DTRACEIOC | 4)         /* snapshot buffer */ 
1420 #define DTRACEIOC_PROBEMATCH    (DTRACEIOC | 5)         /* match probes */ 
1421 #define DTRACEIOC_ENABLE        (DTRACEIOC | 6)         /* enable probes */ 
1422 #define DTRACEIOC_AGGSNAP       (DTRACEIOC | 7)         /* snapshot agg. */ 
1423 #define DTRACEIOC_EPROBE        (DTRACEIOC | 8)         /* get eprobe desc. */ 
1424 #define DTRACEIOC_PROBEARG      (DTRACEIOC | 9)         /* get probe arg */ 
1425 #define DTRACEIOC_CONF          (DTRACEIOC | 10)        /* get config. */ 
1426 #define DTRACEIOC_STATUS        (DTRACEIOC | 11)        /* get status */ 
1427 #define DTRACEIOC_GO            (DTRACEIOC | 12)        /* start tracing */ 
1428 #define DTRACEIOC_STOP          (DTRACEIOC | 13)        /* stop tracing */ 
1429 #define DTRACEIOC_AGGDESC       (DTRACEIOC | 15)        /* get agg. desc. */ 
1430 #define DTRACEIOC_FORMAT        (DTRACEIOC | 16)        /* get format str */ 
1431 #define DTRACEIOC_DOFGET        (DTRACEIOC | 17)        /* get DOF */ 
1432 #define DTRACEIOC_REPLICATE     (DTRACEIOC | 18)        /* replicate enab */ 
1433 #define DTRACEIOC_MODUUIDSLIST  (DTRACEIOC | 30)        /* APPLE ONLY, query for modules with missing symbols */ 
1434 #define DTRACEIOC_PROVMODSYMS   (DTRACEIOC | 31)        /* APPLE ONLY, provide missing symbols for a given module */ 
1435 #define DTRACEIOC_PROCWAITFOR   (DTRACEIOC | 32)        /* APPLE ONLY, wait for process exec */ 
1436 #define DTRACEIOC_SLEEP         (DTRACEIOC | 33)        /* APPLE ONLY, sleep */ 
1437 #define DTRACEIOC_SIGNAL        (DTRACEIOC | 34)        /* APPLE ONLY, signal sleeping process */ 
1440  * The following structs are used to provide symbol information to the kernel from userspace. 
1443 typedef struct dtrace_symbol 
{ 
1444         uint64_t        dtsym_addr
;                     /* address of the symbol */ 
1445         uint64_t        dtsym_size
;                     /* size of the symbol, must be uint64_t to maintain alignment when called by 64b uproc in i386 kernel */ 
1446         char            dtsym_name
[DTRACE_FUNCNAMELEN
]; /* symbol name */ 
1449 typedef struct dtrace_module_symbols 
{ 
1450         UUID            dtmodsyms_uuid
; 
1451         uint64_t        dtmodsyms_count
; 
1452         dtrace_symbol_t dtmodsyms_symbols
[1]; 
1453 } dtrace_module_symbols_t
; 
1455 #define DTRACE_MODULE_SYMBOLS_SIZE(count) (sizeof(dtrace_module_symbols_t) + ((count - 1) * sizeof(dtrace_symbol_t))) 
1457 typedef struct dtrace_module_uuids_list 
{ 
1458         uint64_t        dtmul_count
; 
1460 } dtrace_module_uuids_list_t
; 
1462 #define DTRACE_MODULE_UUIDS_LIST_SIZE(count) (sizeof(dtrace_module_uuids_list_t) + ((count - 1) * sizeof(UUID))) 
1464 typedef struct dtrace_procdesc 
{ 
1465         /* Must be specified by user-space */ 
1467         /* Set or modified by the Kernel */ 
1470 } dtrace_procdesc_t
; 
1473  * DTrace wake reasons. 
1474  * This is used in userspace to determine what's the reason why it woke up, 
1475  * to start aggregating / switching buffer right away if it is because a buffer 
1476  * got over its limit 
1478 #define DTRACE_WAKE_TIMEOUT 0 /* dtrace client woke up because of a timeout */ 
1479 #define DTRACE_WAKE_BUF_LIMIT 1 /* dtrace client woke up because of a over limit buffer */ 
1481 #endif /* __APPLE__ */ 
1486  * In general, DTrace establishes probes in processes and takes actions on 
1487  * processes without knowing their specific user-level structures.  Instead of 
1488  * existing in the framework, process-specific knowledge is contained by the 
1489  * enabling D program -- which can apply process-specific knowledge by making 
1490  * appropriate use of DTrace primitives like copyin() and copyinstr() to 
1491  * operate on user-level data.  However, there may exist some specific probes 
1492  * of particular semantic relevance that the application developer may wish to 
1493  * explicitly export.  For example, an application may wish to export a probe 
1494  * at the point that it begins and ends certain well-defined transactions.  In 
1495  * addition to providing probes, programs may wish to offer assistance for 
1496  * certain actions.  For example, in highly dynamic environments (e.g., Java), 
1497  * it may be difficult to obtain a stack trace in terms of meaningful symbol 
1498  * names (the translation from instruction addresses to corresponding symbol 
1499  * names may only be possible in situ); these environments may wish to define 
1500  * a series of actions to be applied in situ to obtain a meaningful stack 
1503  * These two mechanisms -- user-level statically defined tracing and assisting 
1504  * DTrace actions -- are provided via DTrace _helpers_.  Helpers are specified 
1505  * via DOF, but unlike enabling DOF, helper DOF may contain definitions of 
1506  * providers, probes and their arguments.  If a helper wishes to provide 
1507  * action assistance, probe descriptions and corresponding DIF actions may be 
1508  * specified in the helper DOF.  For such helper actions, however, the probe 
1509  * description describes the specific helper:  all DTrace helpers have the 
1510  * provider name "dtrace" and the module name "helper", and the name of the 
1511  * helper is contained in the function name (for example, the ustack() helper 
1512  * is named "ustack").  Any helper-specific name may be contained in the name 
1513  * (for example, if a helper were to have a constructor, it might be named 
1514  * "dtrace:helper:<helper>:init").  Helper actions are only called when the 
1515  * action that they are helping is taken.  Helper actions may only return DIF 
1516  * expressions, and may only call the following subroutines: 
1518  *    alloca()      <= Allocates memory out of the consumer's scratch space 
1519  *    bcopy()       <= Copies memory to scratch space 
1520  *    copyin()      <= Copies memory from user-level into consumer's scratch 
1521  *    copyinto()    <= Copies memory into a specific location in scratch 
1522  *    copyinstr()   <= Copies a string into a specific location in scratch 
1524  * Helper actions may only access the following built-in variables: 
1526  *    curthread     <= Current kthread_t pointer 
1527  *    tid           <= Current thread identifier 
1528  *    pid           <= Current process identifier 
1529  *    ppid          <= Parent process identifier 
1530  *    uid           <= Current user ID 
1531  *    gid           <= Current group ID 
1532  *    execname      <= Current executable name 
1533  *    zonename      <= Current zone name 
1535  * Helper actions may not manipulate or allocate dynamic variables, but they 
1536  * may have clause-local and statically-allocated global variables.  The 
1537  * helper action variable state is specific to the helper action -- variables 
1538  * used by the helper action may not be accessed outside of the helper 
1539  * action, and the helper action may not access variables that like outside 
1540  * of it.  Helper actions may not load from kernel memory at-large; they are 
1541  * restricting to loading current user state (via copyin() and variants) and 
1542  * scratch space.  As with probe enablings, helper actions are executed in 
1543  * program order.  The result of the helper action is the result of the last 
1544  * executing helper expression. 
1546  * Helpers -- composed of either providers/probes or probes/actions (or both) 
1547  * -- are added by opening the "helper" minor node, and issuing an ioctl(2) 
1548  * (DTRACEHIOC_ADDDOF) that specifies the dof_helper_t structure. This 
1549  * encapsulates the name and base address of the user-level library or 
1550  * executable publishing the helpers and probes as well as the DOF that 
1551  * contains the definitions of those helpers and probes. 
1553  * The DTRACEHIOC_ADD and DTRACEHIOC_REMOVE are left in place for legacy 
1554  * helpers and should no longer be used.  No other ioctls are valid on the 
1555  * helper minor node. 
1557 #if !defined(__APPLE__) 
1558 #define DTRACEHIOC              (('d' << 24) | ('t' << 16) | ('h' << 8)) 
1559 #define DTRACEHIOC_ADD          (DTRACEHIOC | 1)        /* add helper */ 
1560 #define DTRACEHIOC_REMOVE       (DTRACEHIOC | 2)        /* remove helper */ 
1561 #define DTRACEHIOC_ADDDOF       (DTRACEHIOC | 3)        /* add helper DOF */ 
1563 #define DTRACEHIOC_REMOVE       _IO('h', 2)                     /* remove helper */ 
1564 #define DTRACEHIOC_ADDDOF       _IOW('h', 4, user_addr_t)       /* add helper DOF */ 
1565 #endif /* __APPLE__ */ 
1567 typedef struct dof_helper 
{ 
1568         char dofhp_mod
[DTRACE_MODNAMELEN
];      /* executable or library name */ 
1569         uint64_t dofhp_addr
;                    /* base address of object */ 
1570         uint64_t dofhp_dof
;                     /* address of helper DOF */ 
1573 #if defined(__APPLE__) 
1575  * This structure is used to register one or more dof_helper_t(s). 
1576  * For counts greater than one, malloc the structure as if the 
1577  * dofiod_helpers field was "count" sized. The kernel will copyin 
1580  * sizeof(dof_ioctl_data_t) + ((count - 1) * sizeof(dof_helper_t)) 
1582 typedef struct dof_ioctl_data 
{ 
1584          * This field must be 64 bits to keep the alignment the same 
1585          * when 64 bit user procs are sending data to 32 bit xnu 
1587         uint64_t dofiod_count
; 
1588         dof_helper_t dofiod_helpers
[1]; 
1591 #define DOF_IOCTL_DATA_T_SIZE(count) (sizeof(dof_ioctl_data_t) + ((count - 1) * sizeof(dof_helper_t))) 
1595 #define DTRACEMNR_DTRACE        "dtrace"        /* node for DTrace ops */ 
1596 #if !defined(__APPLE__) 
1597 #define DTRACEMNR_HELPER        "helper"        /* node for helpers */ 
1599 #define DTRACEMNR_HELPER        "dtracehelper"  /* node for helpers */ 
1600 #endif /* __APPLE__ */ 
1601 #define DTRACEMNRN_DTRACE       0               /* minor for DTrace ops */ 
1602 #define DTRACEMNRN_HELPER       1               /* minor for helpers */ 
1603 #define DTRACEMNRN_CLONE        2               /* first clone minor */ 
1608  * DTrace Provider API 
1610  * The following functions are implemented by the DTrace framework and are 
1611  * used to implement separate in-kernel DTrace providers.  Common functions 
1612  * are provided in uts/common/os/dtrace.c.  ISA-dependent subroutines are 
1613  * defined in uts/<isa>/dtrace/dtrace_asm.s or uts/<isa>/dtrace/dtrace_isa.c. 
1615  * The provider API has two halves:  the API that the providers consume from 
1616  * DTrace, and the API that providers make available to DTrace. 
1618  * 1 Framework-to-Provider API 
1622  * The Framework-to-Provider API is represented by the dtrace_pops structure 
1623  * that the provider passes to the framework when registering itself.  This 
1624  * structure consists of the following members: 
1626  *   dtps_provide()          <-- Provide all probes, all modules 
1627  *   dtps_provide_module()   <-- Provide all probes in specified module 
1628  *   dtps_enable()           <-- Enable specified probe 
1629  *   dtps_disable()          <-- Disable specified probe 
1630  *   dtps_suspend()          <-- Suspend specified probe 
1631  *   dtps_resume()           <-- Resume specified probe 
1632  *   dtps_getargdesc()       <-- Get the argument description for args[X] 
1633  *   dtps_getargval()        <-- Get the value for an argX or args[X] variable 
1634  *   dtps_usermode()         <-- Find out if the probe was fired in user mode 
1635  *   dtps_destroy()          <-- Destroy all state associated with this probe 
1637  * 1.2  void dtps_provide(void *arg, const dtrace_probedesc_t *spec) 
1641  *   Called to indicate that the provider should provide all probes.  If the 
1642  *   specified description is non-NULL, dtps_provide() is being called because 
1643  *   no probe matched a specified probe -- if the provider has the ability to 
1644  *   create custom probes, it may wish to create a probe that matches the 
1645  *   specified description. 
1647  * 1.2.2  Arguments and notes 
1649  *   The first argument is the cookie as passed to dtrace_register().  The 
1650  *   second argument is a pointer to a probe description that the provider may 
1651  *   wish to consider when creating custom probes.  The provider is expected to 
1652  *   call back into the DTrace framework via dtrace_probe_create() to create 
1653  *   any necessary probes.  dtps_provide() may be called even if the provider 
1654  *   has made available all probes; the provider should check the return value 
1655  *   of dtrace_probe_create() to handle this case.  Note that the provider need 
1656  *   not implement both dtps_provide() and dtps_provide_module(); see 
1657  *   "Arguments and Notes" for dtrace_register(), below. 
1659  * 1.2.3  Return value 
1663  * 1.2.4  Caller's context 
1665  *   dtps_provide() is typically called from open() or ioctl() context, but may 
1666  *   be called from other contexts as well.  The DTrace framework is locked in 
1667  *   such a way that providers may not register or unregister.  This means that 
1668  *   the provider may not call any DTrace API that affects its registration with 
1669  *   the framework, including dtrace_register(), dtrace_unregister(), 
1670  *   dtrace_invalidate(), and dtrace_condense().  However, the context is such 
1671  *   that the provider may (and indeed, is expected to) call probe-related 
1672  *   DTrace routines, including dtrace_probe_create(), dtrace_probe_lookup(), 
1673  *   and dtrace_probe_arg(). 
1675  * 1.3  void dtps_provide_module(void *arg, struct modctl *mp) 
1679  *   Called to indicate that the provider should provide all probes in the 
1682  * 1.3.2  Arguments and notes 
1684  *   The first argument is the cookie as passed to dtrace_register().  The 
1685  *   second argument is a pointer to a modctl structure that indicates the 
1686  *   module for which probes should be created. 
1688  * 1.3.3  Return value 
1692  * 1.3.4  Caller's context 
1694  *   dtps_provide_module() may be called from open() or ioctl() context, but 
1695  *   may also be called from a module loading context.  mod_lock is held, and 
1696  *   the DTrace framework is locked in such a way that providers may not 
1697  *   register or unregister.  This means that the provider may not call any 
1698  *   DTrace API that affects its registration with the framework, including 
1699  *   dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 
1700  *   dtrace_condense().  However, the context is such that the provider may (and 
1701  *   indeed, is expected to) call probe-related DTrace routines, including 
1702  *   dtrace_probe_create(), dtrace_probe_lookup(), and dtrace_probe_arg().  Note 
1703  *   that the provider need not implement both dtps_provide() and 
1704  *   dtps_provide_module(); see "Arguments and Notes" for dtrace_register(), 
1707  * 1.4  int dtps_enable(void *arg, dtrace_id_t id, void *parg) 
1711  *   Called to enable the specified probe. 
1713  * 1.4.2  Arguments and notes 
1715  *   The first argument is the cookie as passed to dtrace_register().  The 
1716  *   second argument is the identifier of the probe to be enabled.  The third 
1717  *   argument is the probe argument as passed to dtrace_probe_create(). 
1718  *   dtps_enable() will be called when a probe transitions from not being 
1719  *   enabled at all to having one or more ECB.  The number of ECBs associated 
1720  *   with the probe may change without subsequent calls into the provider. 
1721  *   When the number of ECBs drops to zero, the provider will be explicitly 
1722  *   told to disable the probe via dtps_disable().  dtrace_probe() should never 
1723  *   be called for a probe identifier that hasn't been explicitly enabled via 
1726  * 1.4.3  Return value 
1728  *   On success, dtps_enable() should return 0. On failure, -1 should be 
1731  * 1.4.4  Caller's context 
1733  *   The DTrace framework is locked in such a way that it may not be called 
1734  *   back into at all.  cpu_lock is held.  mod_lock is not held and may not 
1737  * 1.5  void dtps_disable(void *arg, dtrace_id_t id, void *parg) 
1741  *   Called to disable the specified probe. 
1743  * 1.5.2  Arguments and notes 
1745  *   The first argument is the cookie as passed to dtrace_register().  The 
1746  *   second argument is the identifier of the probe to be disabled.  The third 
1747  *   argument is the probe argument as passed to dtrace_probe_create(). 
1748  *   dtps_disable() will be called when a probe transitions from being enabled 
1749  *   to having zero ECBs.  dtrace_probe() should never be called for a probe 
1750  *   identifier that has been explicitly enabled via dtps_disable(). 
1752  * 1.5.3  Return value 
1756  * 1.5.4  Caller's context 
1758  *   The DTrace framework is locked in such a way that it may not be called 
1759  *   back into at all.  cpu_lock is held.  mod_lock is not held and may not 
1762  * 1.6  void dtps_suspend(void *arg, dtrace_id_t id, void *parg) 
1766  *   Called to suspend the specified enabled probe.  This entry point is for 
1767  *   providers that may need to suspend some or all of their probes when CPUs 
1768  *   are being powered on or when the boot monitor is being entered for a 
1769  *   prolonged period of time. 
1771  * 1.6.2  Arguments and notes 
1773  *   The first argument is the cookie as passed to dtrace_register().  The 
1774  *   second argument is the identifier of the probe to be suspended.  The 
1775  *   third argument is the probe argument as passed to dtrace_probe_create(). 
1776  *   dtps_suspend will only be called on an enabled probe.  Providers that 
1777  *   provide a dtps_suspend entry point will want to take roughly the action 
1778  *   that it takes for dtps_disable. 
1780  * 1.6.3  Return value 
1784  * 1.6.4  Caller's context 
1786  *   Interrupts are disabled.  The DTrace framework is in a state such that the 
1787  *   specified probe cannot be disabled or destroyed for the duration of 
1788  *   dtps_suspend().  As interrupts are disabled, the provider is afforded 
1789  *   little latitude; the provider is expected to do no more than a store to 
1792  * 1.7  void dtps_resume(void *arg, dtrace_id_t id, void *parg) 
1796  *   Called to resume the specified enabled probe.  This entry point is for 
1797  *   providers that may need to resume some or all of their probes after the 
1798  *   completion of an event that induced a call to dtps_suspend(). 
1800  * 1.7.2  Arguments and notes 
1802  *   The first argument is the cookie as passed to dtrace_register().  The 
1803  *   second argument is the identifier of the probe to be resumed.  The 
1804  *   third argument is the probe argument as passed to dtrace_probe_create(). 
1805  *   dtps_resume will only be called on an enabled probe.  Providers that 
1806  *   provide a dtps_resume entry point will want to take roughly the action 
1807  *   that it takes for dtps_enable. 
1809  * 1.7.3  Return value 
1813  * 1.7.4  Caller's context 
1815  *   Interrupts are disabled.  The DTrace framework is in a state such that the 
1816  *   specified probe cannot be disabled or destroyed for the duration of 
1817  *   dtps_resume().  As interrupts are disabled, the provider is afforded 
1818  *   little latitude; the provider is expected to do no more than a store to 
1821  * 1.8  void dtps_getargdesc(void *arg, dtrace_id_t id, void *parg, 
1822  *           dtrace_argdesc_t *desc) 
1826  *   Called to retrieve the argument description for an args[X] variable. 
1828  * 1.8.2  Arguments and notes 
1830  *   The first argument is the cookie as passed to dtrace_register(). The 
1831  *   second argument is the identifier of the current probe. The third 
1832  *   argument is the probe argument as passed to dtrace_probe_create(). The 
1833  *   fourth argument is a pointer to the argument description.  This 
1834  *   description is both an input and output parameter:  it contains the 
1835  *   index of the desired argument in the dtargd_ndx field, and expects 
1836  *   the other fields to be filled in upon return.  If there is no argument 
1837  *   corresponding to the specified index, the dtargd_ndx field should be set 
1838  *   to DTRACE_ARGNONE. 
1840  * 1.8.3  Return value 
1842  *   None.  The dtargd_ndx, dtargd_native, dtargd_xlate and dtargd_mapping 
1843  *   members of the dtrace_argdesc_t structure are all output values. 
1845  * 1.8.4  Caller's context 
1847  *   dtps_getargdesc() is called from ioctl() context. mod_lock is held, and 
1848  *   the DTrace framework is locked in such a way that providers may not 
1849  *   register or unregister.  This means that the provider may not call any 
1850  *   DTrace API that affects its registration with the framework, including 
1851  *   dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and 
1852  *   dtrace_condense(). 
1854  * 1.9  uint64_t dtps_getargval(void *arg, dtrace_id_t id, void *parg, 
1855  *               int argno, int aframes) 
1859  *   Called to retrieve a value for an argX or args[X] variable. 
1861  * 1.9.2  Arguments and notes 
1863  *   The first argument is the cookie as passed to dtrace_register(). The 
1864  *   second argument is the identifier of the current probe. The third 
1865  *   argument is the probe argument as passed to dtrace_probe_create(). The 
1866  *   fourth argument is the number of the argument (the X in the example in 
1867  *   1.9.1). The fifth argument is the number of stack frames that were used 
1868  *   to get from the actual place in the code that fired the probe to 
1869  *   dtrace_probe() itself, the so-called artificial frames. This argument may 
1870  *   be used to descend an appropriate number of frames to find the correct 
1871  *   values. If this entry point is left NULL, the dtrace_getarg() built-in 
1874  * 1.9.3  Return value 
1876  *   The value of the argument. 
1878  * 1.9.4  Caller's context 
1880  *   This is called from within dtrace_probe() meaning that interrupts 
1881  *   are disabled. No locks should be taken within this entry point. 
1883  * 1.10  int dtps_usermode(void *arg, dtrace_id_t id, void *parg) 
1887  *   Called to determine if the probe was fired in a user context. 
1889  * 1.10.2  Arguments and notes 
1891  *   The first argument is the cookie as passed to dtrace_register(). The 
1892  *   second argument is the identifier of the current probe. The third 
1893  *   argument is the probe argument as passed to dtrace_probe_create().  This 
1894  *   entry point must not be left NULL for providers whose probes allow for 
1895  *   mixed mode tracing, that is to say those probes that can fire during 
1896  *   kernel- _or_ user-mode execution 
1898  * 1.10.3  Return value 
1902  * 1.10.4  Caller's context 
1904  *   This is called from within dtrace_probe() meaning that interrupts 
1905  *   are disabled. No locks should be taken within this entry point. 
1907  * 1.11 void dtps_destroy(void *arg, dtrace_id_t id, void *parg) 
1911  *   Called to destroy the specified probe. 
1913  * 1.11.2 Arguments and notes 
1915  *   The first argument is the cookie as passed to dtrace_register().  The 
1916  *   second argument is the identifier of the probe to be destroyed.  The third 
1917  *   argument is the probe argument as passed to dtrace_probe_create().  The 
1918  *   provider should free all state associated with the probe.  The framework 
1919  *   guarantees that dtps_destroy() is only called for probes that have either 
1920  *   been disabled via dtps_disable() or were never enabled via dtps_enable(). 
1921  *   Once dtps_disable() has been called for a probe, no further call will be 
1922  *   made specifying the probe. 
1924  * 1.11.3 Return value 
1928  * 1.11.4 Caller's context 
1930  *   The DTrace framework is locked in such a way that it may not be called 
1931  *   back into at all.  mod_lock is held.  cpu_lock is not held, and may not be 
1935  * 2 Provider-to-Framework API 
1939  * The Provider-to-Framework API provides the mechanism for the provider to 
1940  * register itself with the DTrace framework, to create probes, to lookup 
1941  * probes and (most importantly) to fire probes.  The Provider-to-Framework 
1944  *   dtrace_register()       <-- Register a provider with the DTrace framework 
1945  *   dtrace_unregister()     <-- Remove a provider's DTrace registration 
1946  *   dtrace_invalidate()     <-- Invalidate the specified provider 
1947  *   dtrace_condense()       <-- Remove a provider's unenabled probes 
1948  *   dtrace_attached()       <-- Indicates whether or not DTrace has attached 
1949  *   dtrace_probe_create()   <-- Create a DTrace probe 
1950  *   dtrace_probe_lookup()   <-- Lookup a DTrace probe based on its name 
1951  *   dtrace_probe_arg()      <-- Return the probe argument for a specific probe 
1952  *   dtrace_probe()          <-- Fire the specified probe 
1954  * 2.2  int dtrace_register(const char *name, const dtrace_pattr_t *pap, 
1955  *          uint32_t priv, cred_t *cr, const dtrace_pops_t *pops, void *arg, 
1956  *          dtrace_provider_id_t *idp) 
1960  *   dtrace_register() registers the calling provider with the DTrace 
1961  *   framework.  It should generally be called by DTrace providers in their 
1962  *   attach(9E) entry point. 
1964  * 2.2.2  Arguments and Notes 
1966  *   The first argument is the name of the provider.  The second argument is a 
1967  *   pointer to the stability attributes for the provider.  The third argument 
1968  *   is the privilege flags for the provider, and must be some combination of: 
1970  *     DTRACE_PRIV_NONE     <= All users may enable probes from this provider 
1972  *     DTRACE_PRIV_PROC     <= Any user with privilege of PRIV_DTRACE_PROC may 
1973  *                             enable probes from this provider 
1975  *     DTRACE_PRIV_USER     <= Any user with privilege of PRIV_DTRACE_USER may 
1976  *                             enable probes from this provider 
1978  *     DTRACE_PRIV_KERNEL   <= Any user with privilege of PRIV_DTRACE_KERNEL 
1979  *                             may enable probes from this provider 
1981  *     DTRACE_PRIV_OWNER    <= This flag places an additional constraint on 
1982  *                             the privilege requirements above. These probes 
1983  *                             require either (a) a user ID matching the user 
1984  *                             ID of the cred passed in the fourth argument 
1985  *                             or (b) the PRIV_PROC_OWNER privilege. 
1987  *     DTRACE_PRIV_ZONEOWNER<= This flag places an additional constraint on 
1988  *                             the privilege requirements above. These probes 
1989  *                             require either (a) a zone ID matching the zone 
1990  *                             ID of the cred passed in the fourth argument 
1991  *                             or (b) the PRIV_PROC_ZONE privilege. 
1993  *   Note that these flags designate the _visibility_ of the probes, not 
1994  *   the conditions under which they may or may not fire. 
1996  *   The fourth argument is the credential that is associated with the 
1997  *   provider.  This argument should be NULL if the privilege flags don't 
1998  *   include DTRACE_PRIV_OWNER or DTRACE_PRIV_ZONEOWNER.  If non-NULL, the 
1999  *   framework stashes the uid and zoneid represented by this credential 
2000  *   for use at probe-time, in implicit predicates.  These limit visibility 
2001  *   of the probes to users and/or zones which have sufficient privilege to 
2004  *   The fifth argument is a DTrace provider operations vector, which provides 
2005  *   the implementation for the Framework-to-Provider API.  (See Section 1, 
2006  *   above.)  This must be non-NULL, and each member must be non-NULL.  The 
2007  *   exceptions to this are (1) the dtps_provide() and dtps_provide_module() 
2008  *   members (if the provider so desires, _one_ of these members may be left 
2009  *   NULL -- denoting that the provider only implements the other) and (2) 
2010  *   the dtps_suspend() and dtps_resume() members, which must either both be 
2011  *   NULL or both be non-NULL. 
2013  *   The sixth argument is a cookie to be specified as the first argument for 
2014  *   each function in the Framework-to-Provider API.  This argument may have 
2017  *   The final argument is a pointer to dtrace_provider_id_t.  If 
2018  *   dtrace_register() successfully completes, the provider identifier will be 
2019  *   stored in the memory pointed to be this argument.  This argument must be 
2022  * 2.2.3  Return value 
2024  *   On success, dtrace_register() returns 0 and stores the new provider's 
2025  *   identifier into the memory pointed to by the idp argument.  On failure, 
2026  *   dtrace_register() returns an errno: 
2028  *     EINVAL   The arguments passed to dtrace_register() were somehow invalid. 
2029  *              This may because a parameter that must be non-NULL was NULL, 
2030  *              because the name was invalid (either empty or an illegal 
2031  *              provider name) or because the attributes were invalid. 
2033  *   No other failure code is returned. 
2035  * 2.2.4  Caller's context 
2037  *   dtrace_register() may induce calls to dtrace_provide(); the provider must 
2038  *   hold no locks across dtrace_register() that may also be acquired by 
2039  *   dtrace_provide().  cpu_lock and mod_lock must not be held. 
2041  * 2.3  int dtrace_unregister(dtrace_provider_t id) 
2045  *   Unregisters the specified provider from the DTrace framework.  It should 
2046  *   generally be called by DTrace providers in their detach(9E) entry point. 
2048  * 2.3.2  Arguments and Notes 
2050  *   The only argument is the provider identifier, as returned from a 
2051  *   successful call to dtrace_register().  As a result of calling 
2052  *   dtrace_unregister(), the DTrace framework will call back into the provider 
2053  *   via the dtps_destroy() entry point.  Once dtrace_unregister() successfully 
2054  *   completes, however, the DTrace framework will no longer make calls through 
2055  *   the Framework-to-Provider API. 
2057  * 2.3.3  Return value 
2059  *   On success, dtrace_unregister returns 0.  On failure, dtrace_unregister() 
2062  *     EBUSY    There are currently processes that have the DTrace pseudodevice 
2063  *              open, or there exists an anonymous enabling that hasn't yet 
2066  *   No other failure code is returned. 
2068  * 2.3.4  Caller's context 
2070  *   Because a call to dtrace_unregister() may induce calls through the 
2071  *   Framework-to-Provider API, the caller may not hold any lock across 
2072  *   dtrace_register() that is also acquired in any of the Framework-to- 
2073  *   Provider API functions.  Additionally, mod_lock may not be held. 
2075  * 2.4  void dtrace_invalidate(dtrace_provider_id_t id) 
2079  *   Invalidates the specified provider.  All subsequent probe lookups for the 
2080  *   specified provider will fail, but its probes will not be removed. 
2082  * 2.4.2  Arguments and note 
2084  *   The only argument is the provider identifier, as returned from a 
2085  *   successful call to dtrace_register().  In general, a provider's probes 
2086  *   always remain valid; dtrace_invalidate() is a mechanism for invalidating 
2087  *   an entire provider, regardless of whether or not probes are enabled or 
2088  *   not.  Note that dtrace_invalidate() will _not_ prevent already enabled 
2089  *   probes from firing -- it will merely prevent any new enablings of the 
2090  *   provider's probes. 
2092  * 2.5 int dtrace_condense(dtrace_provider_id_t id) 
2096  *   Removes all the unenabled probes for the given provider. This function is 
2097  *   not unlike dtrace_unregister(), except that it doesn't remove the 
2098  *   provider just as many of its associated probes as it can. 
2100  * 2.5.2  Arguments and Notes 
2102  *   As with dtrace_unregister(), the sole argument is the provider identifier 
2103  *   as returned from a successful call to dtrace_register().  As a result of 
2104  *   calling dtrace_condense(), the DTrace framework will call back into the 
2105  *   given provider's dtps_destroy() entry point for each of the provider's 
2108  * 2.5.3  Return value 
2110  *   Currently, dtrace_condense() always returns 0.  However, consumers of this 
2111  *   function should check the return value as appropriate; its behavior may 
2112  *   change in the future. 
2114  * 2.5.4  Caller's context 
2116  *   As with dtrace_unregister(), the caller may not hold any lock across 
2117  *   dtrace_condense() that is also acquired in the provider's entry points. 
2118  *   Also, mod_lock may not be held. 
2120  * 2.6 int dtrace_attached() 
2124  *   Indicates whether or not DTrace has attached. 
2126  * 2.6.2  Arguments and Notes 
2128  *   For most providers, DTrace makes initial contact beyond registration. 
2129  *   That is, once a provider has registered with DTrace, it waits to hear 
2130  *   from DTrace to create probes.  However, some providers may wish to 
2131  *   proactively create probes without first being told by DTrace to do so. 
2132  *   If providers wish to do this, they must first call dtrace_attached() to 
2133  *   determine if DTrace itself has attached.  If dtrace_attached() returns 0, 
2134  *   the provider must not make any other Provider-to-Framework API call. 
2136  * 2.6.3  Return value 
2138  *   dtrace_attached() returns 1 if DTrace has attached, 0 otherwise. 
2140  * 2.7  int dtrace_probe_create(dtrace_provider_t id, const char *mod, 
2141  *          const char *func, const char *name, int aframes, void *arg) 
2145  *   Creates a probe with specified module name, function name, and name. 
2147  * 2.7.2  Arguments and Notes 
2149  *   The first argument is the provider identifier, as returned from a 
2150  *   successful call to dtrace_register().  The second, third, and fourth 
2151  *   arguments are the module name, function name, and probe name, 
2152  *   respectively.  Of these, module name and function name may both be NULL 
2153  *   (in which case the probe is considered to be unanchored), or they may both 
2154  *   be non-NULL.  The name must be non-NULL, and must point to a non-empty 
2157  *   The fifth argument is the number of artificial stack frames that will be 
2158  *   found on the stack when dtrace_probe() is called for the new probe.  These 
2159  *   artificial frames will be automatically be pruned should the stack() or 
2160  *   stackdepth() functions be called as part of one of the probe's ECBs.  If 
2161  *   the parameter doesn't add an artificial frame, this parameter should be 
2164  *   The final argument is a probe argument that will be passed back to the 
2165  *   provider when a probe-specific operation is called.  (e.g., via 
2166  *   dtps_enable(), dtps_disable(), etc.) 
2168  *   Note that it is up to the provider to be sure that the probe that it 
2169  *   creates does not already exist -- if the provider is unsure of the probe's 
2170  *   existence, it should assure its absence with dtrace_probe_lookup() before 
2171  *   calling dtrace_probe_create(). 
2173  * 2.7.3  Return value 
2175  *   dtrace_probe_create() always succeeds, and always returns the identifier 
2176  *   of the newly-created probe. 
2178  * 2.7.4  Caller's context 
2180  *   While dtrace_probe_create() is generally expected to be called from 
2181  *   dtps_provide() and/or dtps_provide_module(), it may be called from other 
2182  *   non-DTrace contexts.  Neither cpu_lock nor mod_lock may be held. 
2184  * 2.8  dtrace_id_t dtrace_probe_lookup(dtrace_provider_t id, const char *mod, 
2185  *          const char *func, const char *name) 
2189  *   Looks up a probe based on provdider and one or more of module name, 
2190  *   function name and probe name. 
2192  * 2.8.2  Arguments and Notes 
2194  *   The first argument is the provider identifier, as returned from a 
2195  *   successful call to dtrace_register().  The second, third, and fourth 
2196  *   arguments are the module name, function name, and probe name, 
2197  *   respectively.  Any of these may be NULL; dtrace_probe_lookup() will return 
2198  *   the identifier of the first probe that is provided by the specified 
2199  *   provider and matches all of the non-NULL matching criteria. 
2200  *   dtrace_probe_lookup() is generally used by a provider to be check the 
2201  *   existence of a probe before creating it with dtrace_probe_create(). 
2203  * 2.8.3  Return value 
2205  *   If the probe exists, returns its identifier.  If the probe does not exist, 
2206  *   return DTRACE_IDNONE. 
2208  * 2.8.4  Caller's context 
2210  *   While dtrace_probe_lookup() is generally expected to be called from 
2211  *   dtps_provide() and/or dtps_provide_module(), it may also be called from 
2212  *   other non-DTrace contexts.  Neither cpu_lock nor mod_lock may be held. 
2214  * 2.9  void *dtrace_probe_arg(dtrace_provider_t id, dtrace_id_t probe) 
2218  *   Returns the probe argument associated with the specified probe. 
2220  * 2.9.2  Arguments and Notes 
2222  *   The first argument is the provider identifier, as returned from a 
2223  *   successful call to dtrace_register().  The second argument is a probe 
2224  *   identifier, as returned from dtrace_probe_lookup() or 
2225  *   dtrace_probe_create().  This is useful if a probe has multiple 
2226  *   provider-specific components to it:  the provider can create the probe 
2227  *   once with provider-specific state, and then add to the state by looking 
2228  *   up the probe based on probe identifier. 
2230  * 2.9.3  Return value 
2232  *   Returns the argument associated with the specified probe.  If the 
2233  *   specified probe does not exist, or if the specified probe is not provided 
2234  *   by the specified provider, NULL is returned. 
2236  * 2.9.4  Caller's context 
2238  *   While dtrace_probe_arg() is generally expected to be called from 
2239  *   dtps_provide() and/or dtps_provide_module(), it may also be called from 
2240  *   other non-DTrace contexts.  Neither cpu_lock nor mod_lock may be held. 
2242  * 2.10  void dtrace_probe(dtrace_id_t probe, uintptr_t arg0, uintptr_t arg1, 
2243  *              uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) 
2247  *   The epicenter of DTrace:  fires the specified probes with the specified 
2250  * 2.10.2  Arguments and Notes 
2252  *   The first argument is a probe identifier as returned by 
2253  *   dtrace_probe_create() or dtrace_probe_lookup().  The second through sixth 
2254  *   arguments are the values to which the D variables "arg0" through "arg4" 
2257  *   dtrace_probe() should be called whenever the specified probe has fired -- 
2258  *   however the provider defines it. 
2260  * 2.10.3  Return value 
2264  * 2.10.4  Caller's context 
2266  *   dtrace_probe() may be called in virtually any context:  kernel, user, 
2267  *   interrupt, high-level interrupt, with arbitrary adaptive locks held, with 
2268  *   dispatcher locks held, with interrupts disabled, etc.  The only latitude 
2269  *   that must be afforded to DTrace is the ability to make calls within 
2270  *   itself (and to its in-kernel subroutines) and the ability to access 
2271  *   arbitrary (but mapped) memory.  On some platforms, this constrains 
2272  *   context.  For example, on UltraSPARC, dtrace_probe() cannot be called 
2273  *   from any context in which TL is greater than zero.  dtrace_probe() may 
2274  *   also not be called from any routine which may be called by dtrace_probe() 
2275  *   -- which includes functions in the DTrace framework and some in-kernel 
2276  *   DTrace subroutines.  All such functions "dtrace_"; providers that 
2277  *   instrument the kernel arbitrarily should be sure to not instrument these 
2280 typedef struct dtrace_pops 
{ 
2281         void (*dtps_provide
)(void *arg
, const dtrace_probedesc_t 
*spec
); 
2282         void (*dtps_provide_module
)(void *arg
, struct modctl 
*mp
); 
2283         int (*dtps_enable
)(void *arg
, dtrace_id_t id
, void *parg
); 
2284         void (*dtps_disable
)(void *arg
, dtrace_id_t id
, void *parg
); 
2285         void (*dtps_suspend
)(void *arg
, dtrace_id_t id
, void *parg
); 
2286         void (*dtps_resume
)(void *arg
, dtrace_id_t id
, void *parg
); 
2287         void (*dtps_getargdesc
)(void *arg
, dtrace_id_t id
, void *parg
, 
2288             dtrace_argdesc_t 
*desc
); 
2289         uint64_t (*dtps_getargval
)(void *arg
, dtrace_id_t id
, void *parg
, 
2290             int argno
, int aframes
); 
2291         int (*dtps_usermode
)(void *arg
, dtrace_id_t id
, void *parg
); 
2292         void (*dtps_destroy
)(void *arg
, dtrace_id_t id
, void *parg
); 
2295 typedef uintptr_t       dtrace_provider_id_t
; 
2297 extern int dtrace_register(const char *, const dtrace_pattr_t 
*, uint32_t, 
2298     cred_t 
*, const dtrace_pops_t 
*, void *, dtrace_provider_id_t 
*); 
2299 extern int dtrace_unregister(dtrace_provider_id_t
); 
2300 extern int dtrace_condense(dtrace_provider_id_t
); 
2301 extern void dtrace_invalidate(dtrace_provider_id_t
); 
2302 extern dtrace_id_t 
dtrace_probe_lookup(dtrace_provider_id_t
, const char *, 
2303     const char *, const char *); 
2304 extern dtrace_id_t 
dtrace_probe_create(dtrace_provider_id_t
, const char *, 
2305     const char *, const char *, int, void *); 
2306 extern void *dtrace_probe_arg(dtrace_provider_id_t
, dtrace_id_t
); 
2307 #if !defined(__APPLE__) 
2308 extern void dtrace_probe(dtrace_id_t
, uintptr_t arg0
, uintptr_t arg1
, 
2309     uintptr_t arg2
, uintptr_t arg3
, uintptr_t arg4
); 
2311 extern void dtrace_probe(dtrace_id_t
, uint64_t arg0
, uint64_t arg1
, 
2312     uint64_t arg2
, uint64_t arg3
, uint64_t arg4
); 
2313 #endif /* __APPLE__ */ 
2316  * DTrace Meta Provider API 
2318  * The following functions are implemented by the DTrace framework and are 
2319  * used to implement meta providers. Meta providers plug into the DTrace 
2320  * framework and are used to instantiate new providers on the fly. At 
2321  * present, there is only one type of meta provider and only one meta 
2322  * provider may be registered with the DTrace framework at a time. The 
2323  * sole meta provider type provides user-land static tracing facilities 
2324  * by taking meta probe descriptions and adding a corresponding provider 
2325  * into the DTrace framework. 
2327  * 1 Framework-to-Provider 
2331  * The Framework-to-Provider API is represented by the dtrace_mops structure 
2332  * that the meta provider passes to the framework when registering itself as 
2333  * a meta provider. This structure consists of the following members: 
2335  *   dtms_create_probe()        <-- Add a new probe to a created provider 
2336  *   dtms_provide_proc()         <-- Create a new provider for a given process 
2337  *   dtms_remove_proc()          <-- Remove a previously created provider 
2339  * 1.2  void dtms_create_probe(void *arg, void *parg, 
2340  *           dtrace_helper_probedesc_t *probedesc); 
2344  *   Called by the DTrace framework to create a new probe in a provider 
2345  *   created by this meta provider. 
2347  * 1.2.2  Arguments and notes 
2349  *   The first argument is the cookie as passed to dtrace_meta_register(). 
2350  *   The second argument is the provider cookie for the associated provider; 
2351  *   this is obtained from the return value of dtms_provide_proc(). The third 
2352  *   argument is the helper probe description. 
2354  * 1.2.3  Return value 
2358  * 1.2.4  Caller's context 
2360  *   dtms_create_probe() is called from either ioctl() or module load context. 
2361  *   The DTrace framework is locked in such a way that meta providers may not 
2362  *   register or unregister. This means that the meta provider cannot call 
2363  *   dtrace_meta_register() or dtrace_meta_unregister(). However, the context is 
2364  *   such that the provider may (and is expected to) call provider-related 
2365  *   DTrace provider APIs including dtrace_probe_create(). 
2367  * 1.3  void *dtms_provide_proc(void *arg, dtrace_meta_provider_t *mprov, 
2372  *   Called by the DTrace framework to instantiate a new provider given the 
2373  *   description of the provider and probes in the mprov argument. The 
2374  *   meta provider should call dtrace_register() to insert the new provider 
2375  *   into the DTrace framework. 
2377  * 1.3.2  Arguments and notes 
2379  *   The first argument is the cookie as passed to dtrace_meta_register(). 
2380  *   The second argument is a pointer to a structure describing the new 
2381  *   helper provider. The third argument is the process identifier for 
2382  *   process associated with this new provider. Note that the name of the 
2383  *   provider as passed to dtrace_register() should be the contatenation of 
2384  *   the dtmpb_provname member of the mprov argument and the processs 
2385  *   identifier as a string. 
2387  * 1.3.3  Return value 
2389  *   The cookie for the provider that the meta provider creates. This is 
2390  *   the same value that it passed to dtrace_register(). 
2392  * 1.3.4  Caller's context 
2394  *   dtms_provide_proc() is called from either ioctl() or module load context. 
2395  *   The DTrace framework is locked in such a way that meta providers may not 
2396  *   register or unregister. This means that the meta provider cannot call 
2397  *   dtrace_meta_register() or dtrace_meta_unregister(). However, the context 
2398  *   is such that the provider may -- and is expected to --  call 
2399  *   provider-related DTrace provider APIs including dtrace_register(). 
2401  * 1.4  void dtms_remove_proc(void *arg, dtrace_meta_provider_t *mprov, 
2406  *   Called by the DTrace framework to remove a provider that had previously 
2407  *   been instantiated via the dtms_provide_pid() entry point. The meta 
2408  *   provider need not remove the provider immediately, but this entry 
2409  *   point indicates that the provider should be removed as soon as possible 
2410  *   using the dtrace_unregister() API. 
2412  * 1.4.2  Arguments and notes 
2414  *   The first argument is the cookie as passed to dtrace_meta_register(). 
2415  *   The second argument is a pointer to a structure describing the helper 
2416  *   provider. The third argument is the process identifier for process 
2417  *   associated with this new provider. 
2419  * 1.4.3  Return value 
2423  * 1.4.4  Caller's context 
2425  *   dtms_remove_proc() is called from either ioctl() or exit() context. 
2426  *   The DTrace framework is locked in such a way that meta providers may not 
2427  *   register or unregister. This means that the meta provider cannot call 
2428  *   dtrace_meta_register() or dtrace_meta_unregister(). However, the context 
2429  *   is such that the provider may -- and is expected to -- call 
2430  *   provider-related DTrace provider APIs including dtrace_unregister(). 
2432 typedef struct dtrace_helper_probedesc 
{ 
2433         char *dthpb_mod
;                        /* probe module */ 
2434         char *dthpb_func
;                       /* probe function */ 
2435         char *dthpb_name
;                       /* probe name */ 
2436         uint64_t dthpb_base
;                    /* base address */ 
2437 #if !defined(__APPLE__) 
2438         uint32_t *dthpb_offs
;                   /* offsets array */ 
2439         uint32_t *dthpb_enoffs
;                 /* is-enabled offsets array */ 
2441         int32_t *dthpb_offs
;                    /* (signed) offsets array */ 
2442         int32_t *dthpb_enoffs
;                  /* (signed) is-enabled offsets array */ 
2444         uint32_t dthpb_noffs
;                   /* offsets count */ 
2445         uint32_t dthpb_nenoffs
;                 /* is-enabled offsets count */ 
2446         uint8_t *dthpb_args
;                    /* argument mapping array */ 
2447         uint8_t dthpb_xargc
;                    /* translated argument count */ 
2448         uint8_t dthpb_nargc
;                    /* native argument count */ 
2449         char *dthpb_xtypes
;                     /* translated types strings */ 
2450         char *dthpb_ntypes
;                     /* native types strings */ 
2451 } dtrace_helper_probedesc_t
; 
2453 typedef struct dtrace_helper_provdesc 
{ 
2454         char *dthpv_provname
;                   /* provider name */ 
2455         dtrace_pattr_t dthpv_pattr
;             /* stability attributes */ 
2456 } dtrace_helper_provdesc_t
; 
2459  * APPLE NOTE: dtms_provide_pid and dtms_remove_pid are replaced with 
2460  * dtms_provide_proc on Darwin, and a proc reference need to be held 
2461  * for the duration of the call. 
2463  * This is due to the fact that proc_find is not re-entrant on Darwin. 
2466 typedef struct dtrace_mops 
{ 
2467         void (*dtms_create_probe
)(void *, void *, dtrace_helper_probedesc_t 
*); 
2468         void *(*dtms_provide_proc
)(void *, dtrace_helper_provdesc_t 
*, proc_t
*); 
2469         void (*dtms_remove_proc
)(void *, dtrace_helper_provdesc_t 
*, proc_t
*); 
2470         char* (*dtms_provider_name
)(void *); 
2473 typedef uintptr_t       dtrace_meta_provider_id_t
; 
2475 extern int dtrace_meta_register(const char *, const dtrace_mops_t 
*, void *, 
2476     dtrace_meta_provider_id_t 
*); 
2477 extern int dtrace_meta_unregister(dtrace_meta_provider_id_t
); 
2480  * DTrace Kernel Hooks 
2482  * The following functions are implemented by the base kernel and form a set of 
2483  * hooks used by the DTrace framework.  DTrace hooks are implemented in either 
2484  * uts/common/os/dtrace_subr.c, an ISA-specific assembly file, or in a 
2485  * uts/<platform>/os/dtrace_subr.c corresponding to each hardware platform. 
2488 typedef enum dtrace_vtime_state 
{ 
2489         DTRACE_VTIME_INACTIVE 
= 0,      /* No DTrace, no TNF */ 
2490         DTRACE_VTIME_ACTIVE
,            /* DTrace virtual time, no TNF */ 
2491         DTRACE_VTIME_INACTIVE_TNF
,      /* No DTrace, TNF active */ 
2492         DTRACE_VTIME_ACTIVE_TNF         
/* DTrace virtual time _and_ TNF */ 
2493 } dtrace_vtime_state_t
; 
2495 extern dtrace_vtime_state_t dtrace_vtime_active
; 
2496 extern void dtrace_vtime_switch(kthread_t 
*next
); 
2497 extern void dtrace_vtime_enable_tnf(void); 
2498 extern void dtrace_vtime_disable_tnf(void); 
2499 extern void dtrace_vtime_enable(void); 
2500 extern void dtrace_vtime_disable(void); 
2502 #if !defined(__APPLE__) 
2505 extern int (*dtrace_pid_probe_ptr
)(struct regs 
*); 
2506 extern int (*dtrace_return_probe_ptr
)(struct regs 
*); 
2508 #if defined (__i386__) || defined(__x86_64__) 
2509 extern int (*dtrace_pid_probe_ptr
)(x86_saved_state_t 
*regs
); 
2510 extern int (*dtrace_return_probe_ptr
)(x86_saved_state_t
* regs
); 
2512 #error architecture not supported 
2514 #endif /* __APPLE__ */ 
2515 extern void (*dtrace_fasttrap_fork_ptr
)(proc_t 
*, proc_t 
*); 
2516 extern void (*dtrace_fasttrap_exec_ptr
)(proc_t 
*); 
2517 extern void (*dtrace_fasttrap_exit_ptr
)(proc_t 
*); 
2518 extern void dtrace_fasttrap_fork(proc_t 
*, proc_t 
*); 
2520 typedef uintptr_t dtrace_icookie_t
; 
2521 typedef void (*dtrace_xcall_t
)(void *); 
2523 extern dtrace_icookie_t 
dtrace_interrupt_disable(void); 
2524 extern void dtrace_interrupt_enable(dtrace_icookie_t
); 
2526 extern void dtrace_membar_producer(void); 
2527 extern void dtrace_membar_consumer(void); 
2529 extern void (*dtrace_cpu_init
)(processorid_t
); 
2530 #if !defined(__APPLE__) 
2531 extern void (*dtrace_modload
)(struct modctl 
*); 
2532 extern void (*dtrace_modunload
)(struct modctl 
*); 
2534 extern int (*dtrace_modload
)(struct kmod_info 
*, uint32_t); 
2535 extern int (*dtrace_modunload
)(struct kmod_info 
*); 
2536 #endif /* __APPLE__ */ 
2537 extern void (*dtrace_helpers_cleanup
)(proc_t
*); 
2538 extern void (*dtrace_helpers_fork
)(proc_t 
*parent
, proc_t 
*child
); 
2539 extern void (*dtrace_cpustart_init
)(void); 
2540 extern void (*dtrace_cpustart_fini
)(void); 
2542 extern void (*dtrace_kreloc_init
)(void); 
2543 extern void (*dtrace_kreloc_fini
)(void); 
2545 extern void (*dtrace_debugger_init
)(void); 
2546 extern void (*dtrace_debugger_fini
)(void); 
2547 extern dtrace_cacheid_t dtrace_predcache_id
; 
2549 extern hrtime_t 
dtrace_gethrtime(void); 
2550 extern void dtrace_sync(void); 
2551 extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); 
2552 extern void dtrace_xcall(processorid_t
, dtrace_xcall_t
, void *); 
2554 extern int dtrace_safe_defer_signal(void); 
2555 extern void dtrace_safe_synchronous_signal(void); 
2557 extern int dtrace_mach_aframes(void); 
2559 #if !defined(__APPLE__) 
2560 #if defined(__i386) || defined(__amd64) 
2561 extern int dtrace_instr_size(uchar_t 
*instr
); 
2562 extern int dtrace_instr_size_isa(uchar_t 
*, model_t
, int *); 
2563 extern void dtrace_invop_add(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 
2564 extern void dtrace_invop_remove(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 
2565 extern void dtrace_invop_callsite(void); 
2569 extern int dtrace_blksuword32(uintptr_t, uint32_t *, int); 
2570 extern void dtrace_getfsr(uint64_t *); 
2573 #if defined(__i386__) || defined(__x86_64__) 
2574 extern int dtrace_instr_size(uchar_t 
*instr
); 
2575 extern int dtrace_instr_size_isa(uchar_t 
*, model_t
, int *); 
2576 extern void dtrace_invop_add(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 
2577 extern void dtrace_invop_remove(int (*)(uintptr_t, uintptr_t *, uintptr_t)); 
2578 extern void *dtrace_invop_callsite_pre
; 
2579 extern void *dtrace_invop_callsite_post
; 
2584 #endif /* __APPLE__ */ 
2586 #define DTRACE_CPUFLAG_ISSET(flag) \ 
2587         (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & (flag)) 
2589 #define DTRACE_CPUFLAG_SET(flag) \ 
2590         (cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= (flag)) 
2592 #define DTRACE_CPUFLAG_CLEAR(flag) \ 
2593         (cpu_core[CPU->cpu_id].cpuc_dtrace_flags &= ~(flag)) 
2595 #endif /* _KERNEL */ 
2599 #if !defined(__APPLE__) 
2600 #if defined(__i386) || defined(__amd64) 
2602 #define DTRACE_INVOP_PUSHL_EBP          1 
2603 #define DTRACE_INVOP_POPL_EBP           2 
2604 #define DTRACE_INVOP_LEAVE              3 
2605 #define DTRACE_INVOP_NOP                4 
2606 #define DTRACE_INVOP_RET                5 
2610 #if defined(__i386__) || defined(__x86_64__) 
2612 #define DTRACE_INVOP_PUSHL_EBP          1 
2613 #define DTRACE_INVOP_POPL_EBP           2 
2614 #define DTRACE_INVOP_LEAVE              3 
2615 #define DTRACE_INVOP_NOP                4 
2616 #define DTRACE_INVOP_RET                5 
2621 #endif /* __APPLE__ */ 
2627 #endif  /* _SYS_DTRACE_H */